如何使用Automapper映射到具有多个实现的类

时间:2018-03-10 11:57:25

标签: c# inheritance automapper

我有JSON格式的配置文件,其中包含我的类的配置列表。我读取了具有所有常见配置的BaseDTO类的配置,并且我想将这些BaseDTO映射到基于字段Type的Base类的特定实现。有没有办法告诉automapper使用一些自定义映射逻辑来告诉它要创建哪个类?

    //Map in automapper: CreateMap<BaseDTO, Base>();

    public class BaseDTO
    {
        public string Type { get; set; }
        // rest of config from json
    }

    public class Base
    {
        public string Type { get; set; }
        // rest of config mapped from BaseDTO
    }

    public class A : Base
    {

    }

    public class B : Base
    {

    }

    public class C : Base
    {

    }

1 个答案:

答案 0 :(得分:2)

您可以使用 ConstructUsing 方法根据 BaseDTO 类的 Type 属性定义要创建的对象,然后在 BeforeMap <中/ em>将源 BaseDTO 实例映射到创建的目标对象。我允许我稍微改变你的课程,例如

public class BaseDTO
{
    public string Type { get; set; }
    public string AValue { get; set; }
    public string BValue { get; set; }
    public string CValue { get; set; }
}

public class Base
{
    public string Type { get; set; }
}

public class A : Base
{
    public string AValue { get; set; }
}

public class B : Base
{
    public string BValue { get; set; }
}

public class C : Base
{
    public string CValue { get; set; }
}

我使用了以下的automapper配置

var configuration = new MapperConfiguration(
    conf =>
    {
        conf.CreateMap<BaseDTO, Base>()
            .ConstructUsing(s => Create(s.Type))
            .BeforeMap((s, d, c) => c.Mapper.Map(s, d));

        conf.CreateMap<BaseDTO, A>();
        conf.CreateMap<BaseDTO, B>();
        conf.CreateMap<BaseDTO, C>();
    });

创建方法的主体是(你可以创建一个单独的工厂类或者它)

private static Base Create(string type)
{
    switch (type)
    {
        case "A":
            return new A();
        case "B":
            return new B();
        case "C":
            return new C();
        default:
            throw new Exception("Unknown type");
    }
}

以下示例显示了它的工作原理(第一个对象映射到 A 类,第二个映射到 B ,...)

var mapper = configuration.CreateMapper();

var dtos = new[]
        {
            new BaseDTO {Type = "A", AValue = "a-value"},
            new BaseDTO {Type = "B", BValue = "b-value"},
            new BaseDTO {Type = "C", CValue = "c-value"}
        };

var result = mapper.Map<Base[]>(dtos);