На каком уровне проекта должна проходить проверка DTO? - PullRequest
10 голосов
/ 30 января 2009

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

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

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

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

Вот объявление интерфейса и 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 для функции передачи объекта по проводам. Я создаю DTO для оформления контрактов между коммуникациями с моим сервисным уровнем.

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 ]

17 голосов
/ 30 января 2009

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

Обычно для наших проектов ответ на вопрос, где они находятся, - это код «перевода», который сопоставляет модель домена DDD с классами PTO. Если это в слое Prensenation (возможно, не очень хороший ответ), то нажмите. слой, где я бы объявил ВОМ. Но чаще всего это «Сервис», который выполняет перевод для вас, и это означает, что и уровень «Сервис», и уровень «Презентация» нуждаются в ссылках на ВОМ и что (как правило) приводит к их объявлению в отдельном, Нейтральный проект / сборка / пространство имен / независимо от того, что ОБА на уровень представления И на сервисный уровень могут ссылаться.

4 голосов
/ 30 января 2009

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

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

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

...