C# AutoMapper 2.2.1 DynamicMap未映射基础类型属性(2.2.0不映射)
我最近从AutoMapper 2.2.0升级到了2.2.1,并且我已经停止正确映射一个通用方法。以下是该方法的伪版本:C# AutoMapper 2.2.1 DynamicMap未映射基础类型属性(2.2.0不映射),c#,automapper,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(); // Afte
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
}
在版本2.2.1中,输出将为:
Male
True
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; }
}
}
命名空间测试映射器
{
使用制度;
班级计划
{
静态void Main(字符串[]参数)
{
测试仪=新测试仪();
tester.Test();
}
}
公共类测试员
{
公开无效测试()
{
var animal=(动物)新人类();
负荷模型(动物);
var人类=(人类)动物;
Console.WriteLine(人类性别);
Console.WriteLine(human.IsEmployed.ToString());
Console.ReadLine();
}
私有void LoadModel(TModel模型),其中TModel:Animal
{
var tim=newdeveloper{Gender=“Male”,IsEmployed=true,KnownLanguages=42};
AutoMapper.Mapper.DynamicMap(tim,模型);
}
}
公共抽象类动物
{
公共字符串{get;set;}
}
公共类人:动物
{
使用公共布尔值{get;set;}
}
公共类开发人员
{
公共字符串{get;set;}
使用公共布尔值{get;set;}
公共int知识语言{get;set;}
}
}
这个问题似乎与人类
作为动物
在绘制地图之前的装箱有关。我并不是说这是一个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);
}
public void DynamicMap(TSource-source,TDestination-destination-destination)
{
类型modelType=typeof(TSource);
Type destinationType=(等于(destination,default(tdestinition))?typeof(tdestinition):destination.GetType();
DynamicMap(源、目标、模型类型、目标类型);
}
在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);
}
public void DynamicMap(TSource-source,TDestination-destination-destination)
{
类型modelType=typeof(TSource);
类型destinationType=typeof(TDestination);
DynamicMap(源、目标、模型类型、目标类型);
}
因此,在2.2.0动态映射中,它实际上意味着目标类型由目标值决定。如果为空(对于引用类型),则从tdestinition获取目标;否则,目标对象实例的类型将决定这一点
在AutoMapper 2.2.1中,TDEstiation的类型始终优先于动物。在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);
}
public void DynamicMap(TSource-source,TDestination-destination-destination)
{
类型modelType=typeof(TSource);
Type destinationType=(等于(destination,default(tdestinition))?typeof(tdestinition):destination.GetType();
DynamicMap(源、目标、模型类型、目标类型);
}
在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);
}
public void DynamicMap(TSource-source,TDestination-destination-destination)
{
类型modelType=typeof(TSource);
类型destinationType=typeof(TDestination);
DynamicMap(源、目标、模型类型、目标类型);
}
因此,在2.2.0动态映射中,它实际上意味着目标类型由目标值决定。如果为空(对于引用类型),则从tdestinition获取目标;否则,目标对象实例的类型将决定这一点
在AutoMapper 2.2.1中,TDestation的类型始终优先于您的情况。您能展示一个完整的代码示例来突出显示问题吗?当然。让我来整理一下,我会编辑我的问题。你能展示一个完整的代码示例来突出这个问题吗?当然。让我来研究一下,然后编辑我的问题。所以在我的示例中,
typeof(tdestation)
返回typeAnimal
,但destination.GetType()
返回typeHuman
。有道理。我假设这个更改是为了避免空引用异常,但它肯定会破坏我的代码。我想我将不得不保留2.2.0版本,除非我知道将使用typeof
而不是.GetType()
来更新代码。啊。谢谢你的信息。已经找到了正确的更新,我需要基于此信息。参考我的示例代码,我简单地修改了这个AutoMapper.Mapper.DynamicMap(tim,model)
到这个AutoMapper.Mapper.DynamicMap(tim,model,tim.GetType(),model.GetType())代码>。感谢aguyngueran的洞察。因此在我的示例中,typeof(tdestation)
返回typeAnimal
,但destination.GetType()
返回typeHuman
。有道理。我假设这个更改是为了避免空引用异常,但它肯定会破坏我的代码。我想我将不得不保留2.2.0版本,除非我知道将使用typeof
而不是.GetType()
来更新代码。啊。谢谢你的信息。已经找到了正确的更新,我需要基于此信息。参考我的示例代码,我简单地修改了这个AutoMapper.Mapper.DynamicMap(tim,model)
到这个AutoMapper.Mapper.DynamicMap(tim,model,tim.GetType(),model.GetType())代码>。感谢阿奎格伦的洞察力。