我最近从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则不会。
答案 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。