Ответ 1
Чтобы ответить на ваш конкретный вопрос, я буду говорить более подробно о вашей архитектуре. Архитектура, которую вы разработали для своего проекта, тонко отличается от типичной архитектуры, используемой с DDD. Хотя способ разделения обязанностей типичен, в DDD классы домена не несут ответственности за их собственную постоянство. На самом деле мантра DDD невосприимчивость к сохранению. Это в основном означает, что классы домена являются персистентностью невежественными - они не имеют метода Save
. Вместо этого службы приложений (уровень фасада приложений в вашей архитектуре) координируют с репозиториями для восстановления и сохранения объектов домена.
Далее, при реализации репозиториев обычно нет необходимости в явном DTO между базовой технологией сохранения и классами домена. С ORM, такими как NHibernate и EF, сопоставление между классами домена и реляционными таблицами выражается либо с помощью классов сопоставления, либо с использованием XML-конфигураций. В результате ваши классы домена отображаются неявно - нет необходимости в DTO. Некоторые случаи требуют DTO, и в этом случае сопоставление между DTO и классом домена должно быть инкапсулировано реализацией репозитория. Это одно место, где вы могли бы вызывать AutoMapper.
Наконец, распространенной практикой является общение между уровнем представления и уровнем приложения/домена с DTO. Чтобы точно определить, где должно происходить сопоставление, вам нужно углубиться в архитектуру, которая наилучшим образом соответствует вашему проекту. Большинство современных DDD-архитектур основаны на гексагональной архитектуре . В гексагональной архитектуре ваш домен находится в центре, а все остальные "слои" адаптируют домен к конкретным технологиям. Например, репозиторий можно рассматривать как adapter между доменом и конкретной технологией базы данных. ASP.NET WebAPI можно рассматривать как адаптер между доменом и HTTP/REST. Аналогично, уровень представления можно рассматривать как адаптер между доменом и конкретным. DTO могут проявляться в каждом из этих адаптеров, и ответственность адаптера заключается в том, чтобы сопоставлять их с этими DTO.
Типичным примером может служить использование служб приложений для создания фасада над вашим доменом. Никаких DTO в игре еще нет. Затем вы создаете сервисный уровень (открыть службу хоста в DDD) с помощью ASP.NET WebAPI - адаптера. Вы создаете специфические DTO для ASP.NET WebAPI, и именно этот адаптер должен сопоставляться с этими DTO и обратно. Поэтому, если вы используете AutoMapper, его следует вызвать в этом слое. Это можно сделать либо явно, либо в aspect-oriented с помощью фильтров действий. То же самое относится к слою представления. Уровень презентации можно связать непосредственно с сервисами приложений или с открытым хостингом ASP.NET WebAPI. В любом случае, слой представления должен отображать между классами домена (из службы приложения или DTO из WebAPI) и его собственных примитивов, таких как ViewModel.