1

我最近从 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属性在Human2.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 版则没有。

4

1 回答 1

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 。

于 2013-04-01T07:46:07.830 回答