AutoMapper 2.2.1 DynamicMap不映射底层类型属性(2.2.0可以)
本文关键字:属性 可以 类型 DynamicMap 映射 AutoMapper | 更新日期: 2023-09-27 18:05:24
我最近从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
实例对应的属性被正确映射到model
实例的ModelBase
属性;升级到2.2.1版本后,ModelBase
上的属性不再映射——没有抛出异常,只是属性没有被设置。
更新:下面是一个演示2.2.0和2.2.1之间区别的具体示例。在2.2.0版本中,输出将是:
Male
True
在2.2.1版本中,输出将是:
Male
False
Human
中的IsEmployed
属性在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
有关。我并不是说这是一个bug,但它在不同版本之间的表现肯定是不同的。
更新2:我的例子中的抽象类是一个转移注意力的东西;如果我使用一个叫做IAnimal
的接口而不是一个叫做Animal
的抽象类,这个例子就成立。这个问题似乎清楚地表明,版本2.2.0在动态映射时考虑了底层类型,而版本2.2.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中动态映射的目标类型是由目标值决定的。如果它为空(对于引用类型),则从TDestination获取目标;否则由目标对象实例的类型决定。
在AutoMapper 2.2.1中,TDestination类型总是优先的,在你的例子中是Animal。