Объекты домена, DTO и модели просмотра
У меня есть приложение ASP.NET MVC 2 с моделью домена POCO и уровнем репозитория NHibernate. Моя модель домена не имеет представления о моих моделях просмотра, поэтому я использую automapper для перехода от viewmodel к объекту и наоборот /versa.
Когда я ввел WCF в мой проект (последнее требование), мне пришло в голову разобраться с отключенными объектами. То есть я извлекаю объект из базы данных с помощью NHibernate, и после того, как этот объект сериализуется, он отключается, и каждая дочерняя коллекция загружается независимо от того, планирую ли я ее использовать, то есть я делаю много ненужной работы с базой данных.
После ознакомления с этим я вижу, что вам настоятельно рекомендуется не подвергать объекты за пределами вашего проекта домена, и вместо этого вы должны использовать DTO.
Я вижу причину этого, но мне трудно понять, как его реализовать.
Я могу отобразить из viewmodel в DTO в ASP.NET MVC, отправить DTO через сервисный уровень и сопоставить DTO с объектом на уровне сервиса? Где я должен определять свои DTO?
Ответы
Ответ 1
Мне нравится, чтобы мой сервисный уровень содержал инкапсулированные внутри него объекты и возвращал/получал только DTO. Я сохраняю контракты на обслуживание, а также DTO в отдельной сборке, которая представляет собой проект MVC и ссылку на реализацию службы.
Внутри реализации вызова службы служба сопоставляет dto с сущностями, а затем взаимодействует с репозиториями и другими объектами по мере необходимости.
В проекте app/mvc я иногда становлюсь ленивым и просто использую DTO как модели для определенных действий (особенно CRUDy). Если мне нужна проекция или что-то в этом роде, тогда я сделаю viewmodel и конвертирую между DTO и viewmodel с automapper и т.д.
Насколько подвержены ваши сущности, это тема много дискуссий. Некоторые люди будут продвигать их до уровня представления/приложения. Я предпочитаю держать их в сервисном слое. Я нахожу, что когда объекты покидают сервисный уровень, вы обнаруживаете, что занимаетесь типом бизнес-логики везде, где они взаимодействуют, вещи, которые, вероятно, должны находиться в службе.
Ответ 2
Я рассматриваю свои DTO как ViewModels, потому что пользовательский интерфейс (приложение MVC) запрашивает их. Вы могли бы пойти Entity → DTO → ViewModel, но я думаю, что это касается разработки, если единственным пользователем вашей услуги является приложение MVC. Если каким-то образом DTO будут фактически использоваться для данных, а не просто для экранных спецификаций, тогда вы, вероятно, должны использовать дополнительное сопоставление.
Я также просто возвратил объекты из моего слоя WCF и позволял автоматически созданным объектам прокси на клиенте быть DTO. Сущности почти становятся DTO из-за прокси-классов, и бизнес-логика не приходит к клиенту.
И, конечно же, это все "зависит от ваших целей". Этот вопрос является пограничным субъективным и аргументированным ИМХО.
Ответ 3
Мне нравится определять DTO в проекте MVC, а затем создавать методы расширения для преобразования из объекта домена в DTO (и наоборот).
Преобразование будет выполняться в mvc-функциях.
Ответ 4
Я только что написал сообщение о способе обойти все эти преобразования DTO ↔ DO. Возможно, вы проверите это http://codeblock.engio.net/?p=17