На каком уровне проекта должен отображаться текущий DTO?

StackOverflow https://stackoverflow.com/questions/494109

Вопрос

У меня есть проект, где мы используем экранные 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 для функции передачи объекта по проводу.Я создаю 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())

Это было полезно?

Решение

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

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

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top