我可以禁用AutoMapper参考缓存吗?

我相信AutoMapper在将对象列表从一种类型映射到另一种类型时正在使用缓存。 看看下面的代码:

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Mapper.CreateMap<Source, Destination>()
                       .ForMember(dest => dest.SomeOtherNumber, opt => opt.Ignore());

            Mapper.AssertConfigurationIsValid();

            var sourceList = new List<Source>();

            var s1 = new Source {SomeNumber = 10};
            var s2 = new Source {SomeNumber = 69};

            sourceList.Add(s1);
            sourceList.Add(s1);
            sourceList.Add(s1);
            sourceList.Add(s2);

            var destList = Mapper.Map<List<Source>, List<Destination>>(sourceList);

            destList[0].SomeOtherNumber = 100;

            destList.ForEach(x => Console.WriteLine("SomeNumber: {0}, SomeOtherNumber: {1}", x.SomeNumber, x.SomeOtherNumber));
            Console.ReadLine();
        }
    }


    public class Source
    {
        public int SomeNumber { get; set; }
    }

    public class Destination
    {
        public int SomeNumber { get; set; }
        public int SomeOtherNumber { get; set; }
    }

}

代码的输出显示,即使我只设置了destList列表中第一个对象的SomeOtherNumber,前三个项目也具有相同的属性值,因为它们引用了相同的对象引用。 我想知道是否可以禁用此行为,所以即使我在源列表中有重复的引用,我也不会在目标列表中重复引用。 这有意义吗?

这里是输出:

SomeNumber: 10, SomeOtherNumber: 100
SomeNumber: 10, SomeOtherNumber: 100
SomeNumber: 10, SomeOtherNumber: 100
SomeNumber: 69, SomeOtherNumber: 0

我想说这是暂时无法用AutoMapper完成的 。 实例缓存内置相当深,目前不能轻松关闭。 尽管你的用例很奇怪......在一个列表中多次使用相同的源对象,但是你仍然想要不同的目标对象在我看来很不寻常。

但它可以用一个非常糟糕的黑客来解决,因为它会关闭全局实例缓存,并依赖AutoMapper的实现细节,所以请谨慎使用它。 如果你仍然想尝试一下, 下面提到的解决方案不适用于Automapper 2.2.0,因为这个bug只在开发分支中修复,所以你需要从源代码构建AutoMapper或等待下一个版本。

但是,这里是细节

实例缓存由TypeMapObjectMapperRegistry.CacheMappingStrategy [source]处理,与所有其他ITypeMapObjectMapper实现都是私有类一样。

但是应该返回所有ITypeMapObjectMapperTypeMapObjectMapperRegistry.AllMappers字段是一个可以覆盖的公共Func

因此,在Mapper类的第一次使用之前添加此代码:

var baseMappers = TypeMapObjectMapperRegistry.AllMappers();
TypeMapObjectMapperRegistry.AllMappers = () => 
    baseMappers.Where(m => m.GetType().Name != "CacheMappingStrategy").ToArray();

Mapper.CreateMap<Source, Destination>();
链接地址: http://www.djcxy.com/p/68643.html

上一篇: Can I disable AutoMapper reference cache?

下一篇: isKindOfClass Behavior