Какой уровень приложения должен содержать реализацию 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.