Как использовать AutoMapper для уровня Presentation и Bisness а также Data?
Нужно AutoMapper регистрировать с помощью Dependency Injection в ASP.NET.CORE. Но как это делать если на уровне пользователя ViewModel, а на уровне бизнес логики DTO, а на уровне данных - Domain Models? Можно как-то сделать глобальную конфигурацию для AutoMapper?
Нет, в доке этого нет. Дока предлагает для маппинга иерархий писать маппинг и для базовых классов и для всех наследников.
Типа такого:
var configuration = new MapperConfiguration(cfg => {
cfg.CreateMap<Order, OrderDto>()
.Include<OnlineOrder, OnlineOrderDto>()
.Include<MailOrder, MailOrderDto>();
cfg.CreateMap<OnlineOrder, OnlineOrderDto>();
cfg.CreateMap<MailOrder, MailOrderDto>();
});
Это всё руками и не очень удобно Поэтому можно при старте, находить рефлексией всех наслеников вашего базового data класса, находить всех наследников вашего базового dto класса, сопоставлять их по имени (например условиться что dto идут с постфиксом Dto) и динамически составлять маппинг
Илья, я про то, что как не нарушить трехслойную логику и при этом мапить объект из слоя данных в бизнес логику и обратно, а также з бизнес логики во слой презентации и обратно.
Конфиграция то для маппера создается одна на один экземпляр, Тогда как сделать два экземпляра маппера и поместить их в класс Startup?
Ну то есть у вас уровень презентации в любом случае знает об остальных слоях? Можете делать конфигурацию в вашем Startup классе, а в те части которые требуют маппер передавать его как интерфейс IMapper. Можете сделать статические методы с частичной конфигурацией маппера в конкретных сборках и вызывать их при конфигурации в Startup
Илья, тогда в сервис и в контроллер передавать конкретные реализации?
Вот у меня в Startup
IMapper mapper = new Mapper(AutoMapperConfig.ConfigureAutoMapper());
services.AddSingleton(mapper);
#Конфигурация маппера
public static class AutoMapperConfig
{
public static MapperConfiguration ConfigureAutoMapper()
{
MapperConfiguration configuration = new MapperConfiguration(confg =>
{
confg.CreateMap<AddPersonViewModel, PersonDTO>();
#и тд
А вот это в статическом классе расширения конфигурации DALServiceExtension в бизнес логике
public static void AddDALServices(this IServiceCollection services)
{
IMapper mapper = new Mapper(AutoMapperConfiguration.ConfigureAutoMapper());
services.AddSingleton(mapper);
#Конфигурация маппера
public static class AutoMapperConfiguration
{
public static MapperConfiguration ConfigureAutoMapper()
{
MapperConfiguration configuration = new MapperConfiguration(confg =>
{
confg.CreateMap<Person, PersonDTO>();.
#и так далее
FairyFox5700, нет не так. На самом деле я не очень понимаю, почему вы паритесь. Единой конфигурации маппера в корне композиции достаточно, и ничему не противоречит, потому что там и так про все эти типы известно
Но если делать частичные конфигурации маппера, то вам нужно взять сигнатуру от метода, который принимает в себя MapperConfiguration. Тогда у вас получится что-то вроде:
MapperConfiguration configuration = new MapperConfiguration(confg =>
{
DataToDtoMapping.Configure(config);
DtoToViewModelMapping.Configure(config);
});
FairyFox5700, а как вы собираетесь этого избежать если в DI контейнере всё равно будете регистрировать все эти типы? Смысл же в том чтобы нижние уровни не знали о верхних, т.к. это помогает их переиспользовать и заменить в случае чего. Корень композиции в любом случае будет знать обо всех типах в дереве ссылок, по определению