AutoMapper 2.2.1 DynamicMap没有映射底层类型属性(2.2.0)

时间:2013-03-22 14:56:14

标签: c# automapper

我最近从AutoMapper 2.2.0升级到2.2.1,并且我已经停止正确映射的通用方法。这是方法的伪版本:

public void LoadModel<TModel>(int id, TModel model) where TModel : ModelBase
{
    var entity = _repo.LoadById(id);
    _mapper.DynamicMap(entity, model);
    model.AfterMap(); // AfterMap is a virtual method in ModelBase
}

ModelBase是由父类的实例继承的抽象类,它传递给此方法。在2.2.0版中,entity实例的相应属性已正确映射到ModelBase实例的model属性;升级到版本2.2.1后,ModelBase上的属性不再映射 - 没有抛出异常,但属性根本没有设置。

更新 下面是一个具体的例子,它展示了2.2.0和2.2.1之间的区别。在2.2.0版中,输出将为:

Male
True

在2.2.1版中,输出将为:

Male
False

IsEmployed中的Human属性未在版本2.2.1中映射,但在版本2.2.0中映射。以下是示例代码:

namespace TestAutomapper
{
    using System;

    class Program
    {
        static void Main(string[] args)
        {
            Tester tester = new Tester();
            tester.Test();
        }
    }

    public class Tester
    {
        public void Test()
        {
            var animal = (Animal)new Human();
            LoadModel(animal);
            var human = (Human)animal;
            Console.WriteLine(human.Gender);
            Console.WriteLine(human.IsEmployed.ToString());
            Console.ReadLine();
        }

        private void LoadModel<TModel>(TModel model) where TModel : Animal
        {
            var tim = new Developer { Gender = "Male", IsEmployed = true, KnownLanguages = 42 };
            AutoMapper.Mapper.DynamicMap(tim, model);
        }
    }

    public abstract class Animal
    {
        public string Gender { get; set; }
    }

    public class Human : Animal
    {
        public bool IsEmployed { get; set; }
    }

    public class Developer
    {
        public string Gender { get; set; }
        public bool IsEmployed { get; set; }
        public int KnownLanguages { get; set; }
    }
}

此问题似乎与Human在获取映射之前作为Animal进行装箱有关。我并不是说这是一个错误,但它在版本之间的表现肯定不同。

更新2 :我的示例中的抽象类是一个红色的鲱鱼;如果我使用名为IAnimal的接口而不是名为Animal的抽象类,则该示例成立。该问题似乎清楚地表明版本2.2.0在动态映射时会考虑底层类型,而版本2.2.1则不会。

1 个答案:

答案 0 :(得分:1)

2.2.0和2.2.1之间存在与动态映射相关的更改。

在2.2.0中,代码如下所示:

public void DynamicMap<TSource, TDestination>(TSource source, TDestination destination)
{
    Type modelType = typeof(TSource);
    Type destinationType = (Equals(destination, default(TDestination)) ? typeof(TDestination) : destination.GetType());

    DynamicMap(source, destination, modelType, destinationType);
}

和2.2.1:

public void DynamicMap<TSource, TDestination>(TSource source, TDestination destination)
{
    Type modelType = typeof(TSource);
    Type destinationType = typeof(TDestination);

    DynamicMap(source, destination, modelType, destinationType);
}

因此有效地表示在2.2.0中动态映射目标类型由目标值决定。如果它为null(对于引用类型),则目标取自TDestination;否则目标对象实例的类型决定了这一点。

在AutoMapper 2.2.1中,TDestination的类型始终优先于您的案例中的Animal。