Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
566 views
in Technique[技术] by (71.8m points)

.net - Is Mapper.Map in AutoMapper thread-safe?

I'm looking up AutoMapper code now (evaluating it for one of projects I'm working on), and, frankly speaking, I'm quite surprised:

  • The library API is based on a single static access point (Mapper type), so generally any of its methods must be thread safe
  • But I didn't find ANY evidence of this in code.

All I was able to find is this issue, but even the statement made there seems incorrect: if Map doesn't use thread-safe data structures internally, it can't be considered as thread-safe as well, if I'm going to call CreateMap in non-concurrent context, but concurrently with Map.

I.e. the only possible usage pattern of AutoMapper in e.g. ASP.NET MVC application is:

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

Obviously, if I'm correct, that's a huge lack.

So I have two questions:

  • Am I correct?
  • If yes, what's the best alternative to AutoMapper that doesn't have this issue?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The linked issue more or less answers your questions:

Mapper.CreateMap is not threadsafe, nor will it ever be. However, Mapper.Map is thread-safe. The Mapper static class is just a thin wrapper on top of the MappingEngine and Configuration objects.

So only use Mapper.CreateMap if you do your configuration in one central place in a threadsafe manner.

Your comment was:

I'm asking this because I'd like to configure automatter in-place, i.e. right before usage. I planned to configure it in non-concurrent context, i.e. ~ lock (mapperConfigLock) { Mapper.CreateMap()....; }, and I fear this is not enough now.

If you are doing in-place configuration just don't use the static Mapper class. As the comment on the github issue suggest use the mapping engine directly:

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);

It's a little bit of more code but you can create your own helpers around it. But everything is local in a given method so no shared state no need to worry about thread safety.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...