Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?
like image 228
Alex Yakunin Avatar asked May 18 '12 08:05

Alex Yakunin


People also ask

Why you should not use AutoMapper?

1. If you use the convention-based mapping and a property is later renamed that becomes a runtime error and a common source of annoying bugs. 2. If you don't use convention-based mapping (ie you explicitly map each property) then you are just using automapper to do your projection, which is unnecessary complexity.

Does AutoMapper map both ways?

Yes, or you can call CreateMap<ModelClass, ViewModelClass>(). ReverseMap() .

Is AutoMapper case sensitive?

Automatically-mapped Properties are now case sensitive · Issue #950 · AutoMapper/AutoMapper · GitHub.


1 Answers

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.

like image 125
nemesv Avatar answered Sep 18 '22 19:09

nemesv