MVC 4 プロジェクトで NServiceBus (3.2.2)、RavenDB (1.2.2017-Unstable)、Windsor (3.0.0.4001) を使用しています。
3 つの異なるメッセージを処理する IHandleMessages クラスがあり、IDocumentSession が必要なため、次のようなプロパティを定義します。
public IDocumentSession DocumentSession { get; set; }
NServiceBus のWeb サイトから RavenDbUnitOfWork 実装をコピーしました
次のように、Windsor コンテナーに IDocumentStore、IDocumentSession、および IManageUnitsOfWork を登録しました。
container.Register(
Component
.For<IManageUnitsOfWork>()
.ImplementedBy<RavenUnitOfWork>()
.LifestyleTransient()
);
container.Register(
Component
.For<IDocumentStore>()
.UsingFactoryMethod(k => DocumentStoreHolder.DocumentStore)
.LifestyleSingleton(),
Component
.For<IDocumentSession>()
.UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
.LifestyleTransient()
);
NServiceBus は私のコンテナーを使用するように構成されています。
Configure.With()
.CastleWindsorBuilder(container);
UnitOfWork とメッセージ ハンドラが DocumentSession の異なるインスタンスを受け取るという問題が発生しています。これは、SaveChanges() が別の DocumentSession で呼び出されるため、メッセージ ハンドラーのセッションに格納されたオブジェクトが保存されないことを意味します。
一時的なライフスタイルを削除すると、さまざまな種類の問題が発生し、RavenDb からオブジェクトを更新するときに同時実行/競合が発生します。これは、(おそらく) メッセージ ハンドラーが、更新されたオブジェクトのキャッシュ バージョンを保持する DocumentSession の同じインスタンスを取得し続けるためです。
アップデート:
示唆されているように、Windsor での IDocumentSession の登録を、次のように Scope ライフスタイルに変更してみました。
Component
.For<IDocumentSession>()
.UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
.LifestyleScope()
これにより、コンテナーが MVC コントローラーを解決しようとすると、スコープが見つからないという例外が発生し、BeginScope() を呼び出すのを忘れたかどうかを尋ねられます。