2

マルチテナント SaaS アプリケーションに NServiceBus と Ninject を使用しています。

ユーザーが Web サイトまたは API にアクセスしている場合、HttpContext Request オブジェクトのホスト名を調べることで、ユーザーが接続しているアカウントを特定し、アカウントに関するさまざまな設定 (そのうちの 1 つが接続先のデータベース) を取得します。残りのリクエストは正しいデータベースに接続されます (その他のさまざまなチェックが行われます)。

私たちの NSB Windows サービスには、接続先のホスト データベースを決定できる共有コンテキストの概念がないため、コマンドを作成したアカウント/データベースを格納する基本コマンド クラスのプロパティを作成しました。メッセージ。

メッセージ ハンドラーが着信メッセージ用に作成されるとき、依存関係の 1 つは、接続先のデータベースの名前を引数として受け取るリポジトリです。

前に述べたように、Ninject は Web リクエストの HttpContext で正しい DB にアクセスできますが、NSB サービスの場合、メッセージ自体に DB の詳細が含まれており、ハンドラーが構築された後にのみアクセスできます。メッセージに含まれています!) リポジトリを正常に構築します。鶏と卵:)

これは長く曲がりくねった質問方法です...

  • Ninject 作成サイクル中にメッセージのプロパティにアクセスする方法はありますか?
  • これは、私のアーキテクチャが「間違っている」ため難しい難しい問題の 1 つに思えますが、そうですか?
  • 「SetDatabase」のようなリポジトリに公開プロパティを配置することは避けたいと思います。これは、簡単に悪用/誤解され、ユーザー データに大混乱を引き起こす可能性があるためです。
  • また、Ninject が使用するリポジトリ ファクトリを作成することも考えましたが、受信メッセージのプロパティにアクセスする方法はまだわかりません。

前もって感謝します!


ソリューションの編集

Udi と​​ Eben からの回答からハイブリッド アプローチを使用することになりました。

私は、送信メッセージの (HttpContext からの) ヘッダーに顧客のアカウント名を追加する API メッセージ用の送信メッセージ ミューテーターを使用しました。次に、NSB Windows サービスで、受信ミューテーターを使用してヘッダーを調べ、Udi の提案に従ってアカウント名を抽出しました。

また、Eben が提案したように、リポジトリに接続文字列/アカウントの詳細を提供するインターフェイスの 2 つのインスタンスを作成しました。1 つは Web リクエストで使用され、もう 1 つは着信ミューテーターによって設定される ThreadStatic タイプであり、Ninject は NSB のリポジトリのインスタンス化に使用されるようにバインドされています。

両方とも正しいとマークすることはできません。申し訳ありませんが、Eben!:)

4

2 に答える 2

0

あなたは間違いなくアーキテクチャの問題を少し抱えているようです。

これを回避するためのオプションは、とによって実装されるのようなものを持つことかもしれませITenantProviderん。Webサイトの場合、httpバージョンをリポジトリに挿入すると、インスタンスに(または必要なものは何でも)要求されます。エンドポイントの実装では、「スレッド静的」実装を使用できます。複数のスレッドからテナントプロバイダーインスタンスにアクセスし、スレッド固有の状態が必要になる可能性があるため、スレッド静的と言います。しかし、あなたがそれをすることに決めたとしても、それはあなた次第です:)HttpTenantProviderThreadStaticTenantProviderTenantProvider.DatabaseName

メッセージ処理の開始時に、スレッドの静的バージョンにキャストして、の行に沿って何かを呼び出すことができます((TheadStaticTenantProvider)TenantProvider).SetCurrentMessage(theMessage)。リポジトリは、メッセージからスレッド静的テナントプロバイダーを介して必要なデータを受信します。

シャトルでは処理パイプラインを使用するため、受信したメッセージを処理するパイプラインにプラグインするモジュールを作成して、テナントプロバイダーにメッセージを設定します。NServiceBusについてはよくわかりませんが、メッセージを受信した後にイベントにフックして、これを設定できるようなものがあるかもしれません。

私は理にかなっていると思います:)

于 2013-01-21T12:22:57.390 に答える
0

そのような作業を行うには、作業単位またはメッセージ ミューテーター フックの使用を検討する必要があります。詳細はこちら:

http://support.nservicebus.com/customer/portal/articles/860275-unit-of-work-in-nservicebus

http://support.nservicebus.com/customer/portal/articles/860492-pipeline-management-using-message-mutators

また、基本クラスに置くのではなく、メッセージのヘッダーを使用してそのような情報を取得することをお勧めします。

于 2013-01-21T12:58:59.457 に答える