我相信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
答案 0 :(得分:4)
我想说目前无法使用AutoMapper 。实例缓存内置很深,目前无法轻松关闭。尽管你的用例很奇怪......在列表中多次拥有相同的源对象但你仍然想要不同的目标对象在我看来是非常不寻常的。
但它可以解决一个非常糟糕的黑客攻击,因为它会关闭全局实例缓存并依赖于AutoMapper的实现细节,所以要小心使用它。如果您仍想尝试,下面提到的解决方案无法使用Automapper 2.2.0 because of a bug,这只在开发分支中修复,因此您需要从源代码构建AutoMapper或等待下一个版本。
但不过这里有细节
实例缓存由TypeMapObjectMapperRegistry.CacheMappingStrategy
[source]处理,就像所有其他ITypeMapObjectMapper
实现都是私有类一样。
但是应该返回所有TypeMapObjectMapperRegistry.AllMappers
的{{1}}字段是可以覆盖的公共ITypeMapObjectMapper
:
因此,在第一次使用Mapper类之前添加此代码 :
Func