Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以禁用自动映射引用缓存吗?_C#_.net_Automapper_Object Reference - Fatal编程技术网

C# 我可以禁用自动映射引用缓存吗?

C# 我可以禁用自动映射引用缓存吗?,c#,.net,automapper,object-reference,C#,.net,Automapper,Object Reference,我相信AutoMapper在将对象列表从一种类型映射到另一种类型时使用的是缓存。请看下面的代码: namespace ConsoleApplication { class Program { static void Main(string[] args) { Mapper.CreateMap<Source, Destination>() .ForMember(dest

我相信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; }
    }

}

我想说,这是AutoMapper目前无法做到的。实例缓存构建得很深,目前无法轻松关闭。虽然你的用例很奇怪。。。在我看来,在一个列表中多次使用同一个源对象,但仍然需要不同的目标对象是非常不寻常的

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

不过,细节如下

实例缓存由
TypeMapObjectMapperRegistry.CacheMappingStrategy
处理,与所有其他
ITypeMappObjectMapper
实现一样,它是一个私有类

但是,
TypeMapObjectMapperRegistry.AllMappers
字段应返回所有
ITypeMappObjectMapper
是一个公共的
Func
,可被覆盖:

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

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

Mapper.CreateMap<Source, Destination>();
var baseMappers=TypeMapObjectMapperRegistry.AllMappers();
TypeMapObjectMapperRegistry.AllMappers=()=>
其中(m=>m.GetType().Name!=“CacheMappingStrategy”).ToArray();
CreateMap();

AutoMapper是一个不错的工具;然而,我们已经转向使用。更易于使用IMO,无需配置/设置,并解决了与AutoMapper OOB共享您看到的参考。我感谢您的评论。当我试图从其他SO问题中弄明白这一点时,我确实看到了提到的Value Injector。如果我不能弄清楚这一点,我可能最终会使用它。如果您将目标更改为结构而不是类,它将正常工作。这有什么坏处?好的,我很感激你提供的信息。我同意用例可能看起来很奇怪,但我觉得认为默认行为总是正确的有点冒昧。非常有趣的bug:)差不多两年后,问题仍然存在。现在的好问题是禁用缓存策略的后果是什么。Mapper.Reset()有帮助吗?
Mapper.Reset()
可能有帮助,但它也会重置所有映射,因此您必须再次调用所有
Mapper.CreateMaps
。因此,最好手动删除
CacheMappingStrategy
var baseMappers = TypeMapObjectMapperRegistry.AllMappers();
TypeMapObjectMapperRegistry.AllMappers = () => 
    baseMappers.Where(m => m.GetType().Name != "CacheMappingStrategy").ToArray();

Mapper.CreateMap<Source, Destination>();