В каком слое проекта должен жить экран 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 с только полями, необходимыми для представления.