我可以禁用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
实现都是私有类一样。
但是应该返回所有ITypeMapObjectMapper
的TypeMapObjectMapperRegistry.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