Can I disable AutoMapper reference cache?
I believe AutoMapper is using a cache when it is mapping lists of objects from one type to another. Take a look at the following code:
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; }
}
}
The output of the code shows that even though I set only the SomeOtherNumber of the first object in the destList list, the first three items have the same property value because they are referencing the same object reference. I would like to know if I can disable this behavior, so even if I have duplicate references in the source list, I will not have duplicate references in the destination list. Does this make sense?
Here's the ouput:
SomeNumber: 10, SomeOtherNumber: 100
SomeNumber: 10, SomeOtherNumber: 100
SomeNumber: 10, SomeOtherNumber: 100
SomeNumber: 69, SomeOtherNumber: 0
I would say this is cannot be done with AutoMapper as the time being . The instance caching is built in pretty deep and currently it can't be turned off easily. Altough your use case is very strange... having the same source object multiple times in a list but you still want different destination objects is quite unusual in my point of view.
But it can be worked around with a pretty bad hack, because it will turn off instance caching globally and relies on the implementation details of AutoMapper so use it carefully. And if you still want to try it out the below mentioned solution is not working with Automapper 2.2.0 because of a bug which is only fixed in the development branch so you need to build AutoMapper from source or wait for the next release.
But nevertheless here are the details
The instance caching is handled by the TypeMapObjectMapperRegistry.CacheMappingStrategy
[source] which like all the other ITypeMapObjectMapper
implementation is a private class.
However the TypeMapObjectMapperRegistry.AllMappers
field which should return all the ITypeMapObjectMapper
is a public Func
which can be overridden:
So add this code before the first usage of the Mapper class :
var baseMappers = TypeMapObjectMapperRegistry.AllMappers();
TypeMapObjectMapperRegistry.AllMappers = () =>
baseMappers.Where(m => m.GetType().Name != "CacheMappingStrategy").ToArray();
Mapper.CreateMap<Source, Destination>();
链接地址: http://www.djcxy.com/p/68644.html
上一篇: C ++代码迁移:处理未初始化的指针