AutoMapper. Мапинг из DTO/ViewModel в Domain.Entity
Я стараюсь не создавать ViewModel'и и DTO, пока это возможно. Но бывает так, что нужно отдать только id, а не всю сущность, например есть Product, у Product есть Category. А хотим мы отдать JSON в котором будет просто CategoryId. Тут все ясно, просто мапим Product.Category.Id -> в productDto.categoryId.
Обратная ситуация: нам приходит тот самый productDto. Создать обратный мапинг не сложно, но я не нашел способа внедрять зависимости в резолявщие методы. В лучшем случае, я могу создать свой TypeResolver, но все-равно мне внутри придется тянуться к какому-нибудь статическому методу, чтобы получить UoW. А это обернется для меня проблемами в коде тестов. С объектами БД. Можно конечно заигнорить все свойства с Domain.Entity в паминге из DTO в Domain и выставлять их руками, но это уже не так элегантно и можно забыть что-то, в то время, как AutoMapper не позволит забыть, благодаря AssertConfigurationIsValid.
Действительно нельзя никак красиво внедрить зависимости в этом случае или я что-то пропустил?
Вот способ, который мне приходилось применять в проектах компании ByndyuSoft и который я настоятельно рекомендую для подобных щекотливых ситуаций.
1. Создаете публичное свойство в ваших профилях, в которых нужно обращаться к БД и которое будет содержать в себе ссылку на абстрактную фабрику TypeResolver'ов.
2. Регистрируете все Profile в IoC-контейнере на свой тип (практически все мейнстримовые контейнеры это поддерживают, мы используем Castle.Windsor).
3. Регистрируете вашу абстрактную фабрику.
4. Создаете все профили, используя резолвинг через IoC и регистрируете их. Для регистрации профилей рекомендую воспользоваться моей библиотекой NArms.Automapper (есть в NuGet), но вы можете сделать это и вручную.
5. В профиле просто создаете нужный TypeResolver, используя абстрактную фабрику.
Если используется Castle.Windsor, то можете прибегнуть к менее гибкому, но тоже имеющего право на жизнь решению с использованием NArms.Windsor. Статический класс IoC т.о. можно инициализировать, допустим в одном из Installer'ов (я завожу под это дело специальный WindsorInstaller). В таком случае вы можете резолвить что угодно через IoC.Resolve<>(). Способ не очень красивый, да и вы получаете т.о. лишнюю зависимость в сборках с профилями (от Castle.Windsor).
Я правильно, понимаю, что надо просто забыть про статическую обертку Mapper.Map (которая, мне, к слову, не нравилась) и везде работать с профилями и тогда проблема исчезнет сама собой?