如何使用AutoMapper动态映射内部类型

时间:2015-04-07 11:52:14

标签: c# automapper

我定义了以下四个类

   public class Source
    {
        public object Value { get; set; }
    }

    public class Destination
    {
        public object Value { get; set; }
    }

    public class SourceDataType
    {
        //...
    }

    public class DestinationDataType
    {
        //...
    }

我按如下方式配置Automapper

        AutoMapper.Mapper.CreateMap<Source, Destination>();
        AutoMapper.Mapper.CreateMap<SourceDataType, DestinationDataType>();

然后在我的代码中,我创建了一个Source对象,其值为SourceDateType,并尝试将其映射到Destination对象。

        var source = new Source { Value = new SourceDataType() };

        var destination = AutoMapper.Mapper.Map<Source, Destination>(source);

        Console.WriteLine(destination.GetType());
        Console.WriteLine(destination.Value.GetType());

目标类型符合预期。我希望Automapper能够了解SourceDataTypeDestinationDataType之间的映射,并将SourceDataType时刻映射到DestinationDataType瞬间。但是,目标对象的值为SourceDataType

我也尝试了DynamicMap,但取得了相同的结果。

        var destination = AutoMapper.Mapper.DynamicMap<Source, Destination>(source);
        var destination = AutoMapper.Mapper.DynamicMap<Destination>(source);

有没有办法配置Automapper来动态映射内部类?

2 个答案:

答案 0 :(得分:1)

这是可以解决的,但如果混合中添加越来越多的类型,它将变得难以维护和复杂。无论如何,根据您的情况,这将有效:

    [Test]
    public void CustomMapping()
    {
        //arrange
        Mapper.CreateMap<Source, Destination>()
            .ForMember(d=>d.Value, opt=>opt.ResolveUsing(ResolveValue));
        Mapper.CreateMap<SourceDataType, DestinationDataType>();

        var source = new Source { Value = new SourceDataType() };

        //act
        var destination = Mapper.Map<Source, Destination>(source);

        //assert
        destination.Value.Should().Be.OfType<DestinationDataType>();
    }

    private object ResolveValue(ResolutionResult result)
    {
        var source = result.Context.SourceValue as Source;

        if (result.Context.IsSourceValueNull || source == null || !(source.Value is SourceDataType))
        {
            return null;
        }
        var sourceValue = source.Value as SourceDataType;

        return result.Context.Engine.Map<DestinationDataType>(sourceValue);
    }

答案 1 :(得分:0)

这里有两个问题:

首先,您没有定义SourceDataTypeDestinationDataType之间的任何关系,因此AutoMapper无法知道如何转换这些类型。

其次,这两个属性属于object类型(据我所知),AutoMapper不会根据动态类型进行转换。

您可以使用Custom Type Converter来解决此问题;但是,由于属性类型为object,我对此有所保留。

无论如何,您可以尝试根据以下映射添加内容:

Mapper.CreateMap<object, object>().ConvertUsing(src =>
{
    if (src is SourceDataType)
        return new DestinationDataType(); // Put your conversion code here.
    else
        return src;
});

就像我说的,我不喜欢这样,因为object会匹配所有属性类型。