Какой уровень приложения должен содержать реализацию DTO

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

Скажем, я использую трехуровневую архитектуру:

  • Уровень данных (с использованием Entity Framework)
  • Бизнес-уровень (служба WCF)
  • Уровень представления (веб-приложение MVC 4.0)

Где я должен конвертировать из объекта EF Employee в EmployeeDTO POCO?

Предположим, что я выполняю преобразование на уровне доступа к данным, но что происходит в службе WCF? Должен ли он быть преобразован в другой объект DataMember и когда он попадает на уровень пользовательского интерфейса (веб-приложение MVC), следует ли его затем преобразовать в третий раз в модель? Я был бы признателен, если бы кто-то мог очистить это для меня.

Ответы

Ответ 1

В подобной ситуации я использовал dto для Core, который известен всем трем. Таким образом, у вас есть

     Core
       |
 ------------
 |     |    |
DAL   BL   PL

Каждый слой может работать с Core.Dto.Employee. Каждый слой также предоставляет Core.Dto.Employee извне в свой API. Но внутренне каждый слой может преобразовывать/адаптировать Core.Dto.Employee, например. вы читаете из базы данных EF.Employee и позже преобразуете ее в Core.Dto.Employee. Трансформация содержится в границе слоя.

Если у вас есть несколько разных моделей для представления одной и той же вещи во всех слоях, например PL хочет PL.Employee, а DAL работает на EF.Employee, вы получите беспорядок.

Ответ 2

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

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

То, что вы используете в своем бизнесе и на уровне данных, зависит от архитектуры. У вас может быть модель домена, которая сначала сопоставляется с кодом. В этом случае сервисный уровень отображает объекты домена в контракты данных (DTO). Если у вас нет модели домена (анемичная модель), вы можете просто сопоставить базу данных непосредственно с вашими DTO.

Сайт ASP.NET MVC использует эту услугу и отображает полученный DTO для выделения моделей представления, которые затем передаются в конкретное представление.

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

Другие замечания:

  • Не подвергайте свои базы данных объектам.
  • Не конвертируйте в бизнес-уровень, так как это не бизнес-логика.

Ответ 3

Взгляните на fooobar.com/questions/356012/... здесь, так как у меня нет достаточной репутации для добавления комментариев.

Лично я передавал бы сущности между слоем Persistence и вашим бизнес-слоем. По мере того как вы используете MVC, ваши шансы на то, что вы собираетесь просматривать модели просмотра на своих контроллерах. В какой момент я буду сопоставлять вашу модель взгляда с вашими DTO (-ами).

Если вы планируете использовать DTO между всеми вашими слоями, создайте проект перекрестной резки, который вы можете затем ссылаться.

Ответ 4

Подход, который я особенно люблю, - это преобразование DTO в вашем бизнес-слое.

Сценарий: ваш уровень презентации называет ваш бизнес-уровень передачей DTO. Вы выполняете некоторую логику и проверяете, затем конвертируете DTO в объект и отправляете его на уровень доступа к данным.

то есть. UI → Шина. Layer (конвертировать в Entity) → Уровень данных

Мне нравится этот подход, так как я полагаю, что на уровне данных не должно быть никакой логики преобразования и должно получать и обрабатывать объекты по мере необходимости. Другая причина, по которой это эффективно, заключается в том, что теперь вы можете определить конкретные бизнес-правила/логику проверки во время процесса преобразования перед отправкой на уровень данных. Вот старая статья MSDN, но есть некоторые большие подробности, объясняющие аналогичный подход.

Ответ 5

Я использую для этих целей проект с именем Shared, который может совместно использовать объект со всеми слоями. Независимо от имени, он должен быть видимым для всех слоев.

Ответ 6

Не должно быть никакого преобразования. Вы бы просто использовали Poco Objects как DTO.

EF работает с Poco, и они могут быть сериализованы WCF.

Они должны быть определены в сборке, на которую ссылаются все проекты.

В ASP.NET MVC вы могли бы перейти к ViewModel с помощью Poco-DTO.