AutoMapper嵌套映射

时间:2017-01-26 09:04:09

标签: c# .net automapper

所以我有一个用于DI的接口:

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);
    }
}

我将使用以下简化数据模型(&#34;相同&#34;用于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中为Installation配置映射时,它可以正常工作。

我不明白的是,我提供了一种特定的方法来映射嵌套类型&#34;合同&#34;来自&#34;客户&#34;,以及特定的地图&#34;安装&#34;来自&#34; Contract&#34;,那么为什么automapper尝试将其映射配置用于嵌套类型的嵌套类型?他为什么不停在那里并使用我提供的方法?我怎样才能实现我想要做的事情,链接映射器?

1 个答案:

答案 0 :(得分: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接口来解耦我的映射器,因此我可以轻松地注入我的映射器并使用强类型。 Cleaner然后在我的服务Mapper.Map中调用任何地方或在我的服务外观中创建mapper。