AutoMapper中的Mapper.Map线程安全吗?

时间:2012-05-18 08:29:10

标签: .net asp.net-mvc automapper

我现在正在查找AutoMapper代码(对我正在进行的项目进行评估),坦率地说,我很惊讶:

  • 库API基于单个静态访问点(Mapper类型),因此通常其任何方法都必须是线程安全的
  • 但我没有在代码中找到任何证据。

我能找到的只有this issue,但即使是在那里做出的陈述似乎也是错误的:如果Map内部没有使用线程安全的数据结构,则不能将其视为线程-safe,如果我要在非并发上下文中调用CreateMap,但同时与Map调用。

即。 AutoMapper唯一可能的使用模式,例如: ASP.NET MVC应用程序是:

lock (mapperLock) {
    ... Mapper.AnyMethod(...) ...
}

显然,如果我是对的,这是一个巨大的缺失。

所以我有两个问题:

  • 我说错了吗?
  • 如果是,那么没有这个问题的AutoMapper的最佳替代方案是什么?

2 个答案:

答案 0 :(得分:34)

关联的issue或多或少回答了您的问题:

  

Mapper.CreateMap不是线程安全的,也不会是线程安全的。然而,   Mapper.Map是线程安全的。 Mapper静态类只是一个很薄的   包装在MappingEngine和Configuration对象之上。

因此,如果您以线程安全的方式在一个中心位置进行配置,则只能使用Mapper.CreateMap

您的评论是:

  

我问这个是因为我想在原地配置自动机,   即在使用前。我计划在非并发中配置它   context,即~lock(mapperConfigLock){Mapper.CreateMap()....; },   我担心现在还不够。

如果您正在进行就地配置,请不要使用静态Mapper类。由于对github问题的评论建议直接使用映射引擎:

var config = 
    new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers());
config.CreateMap<Source, Destination>();
var engine = new MappingEngine(config);

var source = new Source();
var dest = engine.Map(source);

这是一些更多的代码,但你可以围绕它创建自己的帮助器。 但是在给定的方法中,一切都是本地的,因此没有共享状态就不必担心线程安全。

答案 1 :(得分:0)

这个问题可能有点过时,只想在经过一些调查后记录我的一些调查结果。

Mapper是一个包装类,用于创建新配置,以及静态内存中mapper的新实例,所以严格来说它不是线程安全的,但只要你只是初始化就可以安全使用它配置一次。

MapperConfiguration创建mapper的新实例,并将配置记录在自己的实例内存空间中。

<强> TLDR;

如果只需要初始化配置ONCE,请选择静态API

如果您需要多次初始化配置,并担心线程安全,请选择实例API