33

私は現在AutoMapperコードを調べています (私が取り組んでいるプロジェクトの 1 つについて評価しています)。率直に言って、私は非常に驚いています。

  • ライブラリ API は単一の静的アクセス ポイント (タイプ) に基づいているMapperため、通常、そのメソッドはすべてスレッド セーフである必要があります。
  • しかし、コードでこれに関する証拠は見つかりませんでした。

私が見つけることができたのはこの問題だけですが、そこで行われたステートメントでさえ間違っているようMapです。CreateMap非並行コンテキストで呼び出しますが、 と同時に呼び出しますMap

つまり、ASP.NET MVC アプリケーションなどで AutoMapper を使用できる唯一のパターンは次のとおりです。

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

明らかに、私が正しければ、それは大きな不足です。

だから私は2つの質問があります:

  • 私は正しいですか?
  • はいの場合、この問題がない AutoMapper の最良の代替手段は何ですか?
4

2 に答える 2

36

リンクされた問題は多かれ少なかれあなたの質問に答えます:

Mapper.CreateMap はスレッドセーフではありません。ただし、Mapper.Map はスレッドセーフです。Mapper 静的クラスは、MappingEngine および Configuration オブジェクトの単なる薄いラッパーです。

そのため、スレッドセーフな方法で中央の 1 か所Mapper.CreateMapで構成を行う場合にのみ使用してください。

あなたのコメントは:

automatter をその場で、つまり使用する直前に構成したいので、私はこれを求めています。非並行コンテキストで構成する予定でした。つまり ~ 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);

もう少しコードが増えますが、独自のヘルパーを作成できます。ただし、特定のメソッドではすべてがローカルであるため、共有状態はなく、スレッドの安全性について心配する必要はありません。

于 2012-05-18T09:55:05.700 に答える