2017-01-26 5 views
1

Поэтому у меня есть интерфейс, используемый для DI:AutoMapper Вложенные Отображения

public interface IMapper<in TIn, out TOut> 
{ 
    TOut Map(TIn objectToMap); 
} 

И базовый класс для моих картографов:

public abstract class MapperBase<TIn, TOut> : IMapper<TIn, TOut> 
{ 
    internal IConfigurationProvider MapperConfiguration { get; set; } 

    public TOut Map(TIn objectToMap) 
    { 
     return MapperConfiguration.CreateMapper().Map<TOut>(objectToMap); 
    } 
} 

И я буду использовать упрощенную модель данных (» же»для DAL и обслуживание слоев)

public class Client 
{ 
    public int Id { get; set; } 
    public List<Contract> Contracts { get; set; } 
} 

public class Contract 
{ 
    public int Id { get; set; } 
    public List<Installation> Installations { get; set; } 
} 

public class Installation 
{ 
    public int Id { get; set; } 
} 

у меня есть следующие картографы между моей DAL и службой слоем:

public class DalClientToServiceMapper : MapperBase<DAL.Client, Interface.Model.Client> 
{ 
    public DalClientToServiceMapper(IMapper<DAL.Contract, Interface.Model.Contract> contractMapper) 
    { 
     MapperConfiguration = new MapperConfiguration(cfg => 
     { 
      cfg.CreateMap<DAL.Client, Interface.Model.Client>(); 
      cfg.CreateMap<DAL.Contract, Interface.Model.Contract>().ConstructUsing(contractMapper.Map); 
     }); 
    } 
} 

public class DalContractToServiceMapper : MapperBase<DAL.Contract, Interface.Model.Contract> 
{ 
    public DalContractToServiceMapper(IMapper<DAL.Installation, Interface.Model.Installation> dalInstallationToServiceMapper) 
    { 
     MapperConfiguration = new MapperConfiguration(cfg => 
     { 
      cfg.CreateMap<DAL.Contract, Interface.Model.Contract>(); 
      cfg.CreateMap<DAL.Installation, Interface.Model.Installation>().ConstructUsing(dalInstallationToServiceMapper.Map); 
     }); 
    } 
} 

public class DalInstallationToServiceMapper : MapperBase<DAL.Installation, Interface.Model.Installation> 
{ 
    public DalInstallationToServiceMapper() 
    { 
     MapperConfiguration = new MapperConfiguration(cfg => 
     { 
      cfg.CreateMap<DAL.Installation, Interface.Model.Installation>(); 
     }); 
    } 
} 

Но когда я нахожу карту клиента, AutoMapper дает мне исключение, говорящее, что для установки не существует сопоставления (вложенный вложенный тип).

Когда я настраиваю сопоставление для установки в Client Mapper, он отлично работает.

То, что я не понимаю, я предоставляю конкретный метод для сопоставления вложенного типа «Контракт» с «Клиентом» и конкретным, чтобы отобразить «Установка» из «Контракта», поэтому почему automapper пытается использовать его конфигурацию отображения для вложенных типов вложенных типов? Почему он просто не останавливается там и не использует метод, который я предоставлял? Как я могу достичь того, что я хочу здесь сделать, привязки карт?

ответ

0

Я нашел решение, используя профиль.

Я определяю все мои отображения в классе, производный от профиля:

public class DalToServiceProfile : Profile 
{ 
    protected override void Configure() 
    { 
     CreateMap<DAL.Client, Interface.Model.Client>(); 
     CreateMap<DAL.Installation, Interface.Model.Installation>(); 
     CreateMap<DAL.Contract, Interface.Model.Contract>(); 
    } 
} 

я изменить базовый класс выглядит следующим образом:

public abstract class MapperBase<TIn, TOut, TProfile> : IMapper<TIn, TOut> where TProfile : Profile, new() 
{ 
    internal IConfigurationProvider MapperConfiguration { get; set; } 

    protected MapperBase() 
    { 
     MapperConfiguration = new MapperConfiguration(cfg => 
     { 
      cfg.AddProfile<TProfile>(); 
     }); 
    } 

    public TOut Map(TIn objectToMap) 
    { 
     return MapperConfiguration.CreateMapper().Map<TOut>(objectToMap); 
    } 
} 

И мой Mappers ар Теперь проще:

public class DalClientToServiceMapper : MapperBase<DAL.Client, Interface.Model.Client, DalToServiceProfile> 
{ 
} 

public class DalContractToServiceMapper : MapperBase<DAL.Contract, Interface.Model.Contract, DalToServiceProfile> 
{ 
} 

public class DalInstallationToServiceMapper : MapperBase<DAL.Installation, Interface.Model.Installation, DalToServiceProfile> 
{ 
} 

Мне нужен этот дополнительный слой, поскольку мы используем инъекцию зависимостей и вам нужно вводить карты на основе их интерфейс.

Все мои картографы знают всю конфигурацию отображения, но я не вижу в этом большой сделки.

Также они не привязаны к цепи, но поскольку каждый из них загружает один и тот же профиль, они делают то же самое.

На самом деле все, что я здесь делаю, это развязка моего картографа с помощью интерфейса IMapper, поэтому я могу легко вводить свои картографы и использовать их строго типизированными. Затем очиститель, вызывающий всюду в моих сервисах Mapper.Map или создающий Mapper в моих сервисных фасадах.

Смежные вопросы