В каком слое проекта должен жить экран DTO?

у меня есть проект, где мы используем экран DTO для инкапсуляции данных между Слой Сервиса и Внешний Вид. В нашем случае уровень представления ASP.Net.

единственными классами, которые знают о DTO, являются классы уровня обслуживания и страницы / элементы управления, которые вызывают эти службы и отображают DTO.

DTO почти всегда специфичны для страницы / управления, поэтому я чувствую, что они принадлежат к уровню презентации, но это это означает, что уровень обслуживания должен ссылаться на уровень представления, чтобы использовать DTO.

я почти думаю, что уровень сервиса должен возвращать более богатые объекты (но не объекты домена?) и затем слой презентации может взять эти объекты и сопоставить их с очень конкретными DTO для каждой страницы / элемента управления.

вот объявление интерфейса и DTO, чтобы вы могли видеть, о чем я говорю о компании:

public interface IBlogTasks
{
    BlogPostDisplayDTO GetBlogEntryByTitleAndDate(int year, int month, string urlFriendlyTitle);
}

public class BlogPostDisplayDTO 
{
    public string Title { get; set; }
    public DateTime PostDate { get; set; }
    public string HtmlContent { get; set; }
    public string ImageUrl { get; set; }        
    public string Author { get; set; }
    public int CommentCount { get; set; }
    public string Permalink { get; set; }
}   

редактировать

вот еще один пример кода для описания случая использования, когда модель домена не участвует. Возможно, это немного прояснит ситуацию. Я считаю, что перегружен значением DTO. Я не говорю о DTO для функции передачи объекта по проводу. Я создаю DTOs для формализации контрактов между связью с моим уровнем обслуживания.

public interface IAuthenticationTasks
{
    bool AuthenticateUser(AuthenticationFormDTO authDTO);
}

public class AuthenticationFormDTO
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public bool persistLogin { get; set; }
}

скажем, моя аутентификация внезапно требует Параметр IP-адрес. Теперь я могу добавить это свойство в DTO без необходимости изменять интерфейс контракта.

Я не хочу передавать объекты на уровень презентации. Я не хочу, чтобы мой код, чтобы иметь возможность перейти BlogPost.AddComment(new Comment())

2 ответов


даже думал, что канонический вариант использования для " DTO "является более" сериализуемым объектом, который может быть передан по проводу", в этом случае вы действительно больше ссылаетесь на "объекты представления-передачи" или "модели представления".

обычно для наших проектов ответ на то, где они живут, - это код "перевода", который сопоставляет модель домена DDD классам PTO. Если это в слое Prensenation (возможно, не такой большой ответ), то pres. слой-это то, где я бы объявил Птос. Но чаще всего это "сервис", который выполняет перевод для вас, и это означает, что как "сервис", так и слой "презентация" нуждаются в ссылках на PTOs, и это (обычно) приводит к их объявлению в отдельном нейтральном проекте/сборке/пространстве имен/независимо от того, что может ссылаться как слой презентации, так и слой сервиса.


используете ли вы фактические службы (web или WCF)? Если это так, то определите DTOs в слое сервиса и прокси, созданный при добавлении сервиса (или web, если используется старый ASMX), будет содержать все типы DTO. Это самый простой способ сделать это и поддерживает только свободную связь между вашим ASP.NET проект и ваш сервисный проект-Прямая ссылка на проект не требуется ни в том, ни в другом направлении. По мере обновления DTOs все, что вам нужно сделать, это обновить ссылку на службу, и она будет автоматически предоставлять обновления для веб-проекта через созданный прокси-класс.

в любом случае, если вы следуете чему-то вроде DDD-подхода, лучше всего, чтобы ваши инфраструктурные проекты (например, пользовательский интерфейс для веб-платформы) ссылались на ваши объекты домена, чем наоборот. Однако, если вы последуете моему совету выше, ваш веб-проект не будет иметь прямой зависимости от проекта вообще, что хорошо и, конечно, лучше, чем иметь ваш богатый домен объекты в зависимости от вашего веб - проекта (если это было даже соображение-я понимаю, что вы не говорили, что делаете это).

Если ваши DTOs специфичны для просмотра, я бы включил их в ваш проект пользовательского интерфейса. Это действительно должна быть работа контроллера, чтобы гарантировать, что представление получает только от модели то, что ему нужно, - в вашем случае объект value с только полями, необходимыми для представления.