2017-08-09 16 views
0

私はNinject IoCのカスタムセッションスコープを有効にする機能を実装するのに苦労しています。私の要件は、固有のセッションid(int)に対して、私は特定のインタフェースにバインドされたオブジェクトの新しいインスタンスを取得するということです。 2番目の要件は、Getが呼び出される場所で可能でなければならないことです。オブジェクトのセッションにバインドされたインスタンスを取得するために、セッションIDをNinjectコンテナに渡すにはどうすればよいですか?

問題は、IKernel.Get <>にセッションIDを渡す手段がないことです。静的インスタンスは現在のセッションIDにアクセスできないため、.InScope()も使用できません。 (セッションなし。現在のパターンを使用できます)。

セッションは一意の整数でしか識別できず、複数のセッションが同時に実行される可能性があります。

セッションごとに別々のコンテナを作成することは別として、アイデアはありますか?私はそれが高価かもしれないと思う。コンテナをコピーしていますか? Ninjectで可能ですか?

おかげで、ラデク

+1

オブジェクトグラフの構築を実行時データに依存させないようにします。詳細については、[this](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99)を参照してください。 – Steven

答えて

1

あなたの仮定が間違っています。

  • InScopeは、静的フィールドを必要としません。メソッドシグネチャはInScope(Func<IContext, object> scope)です。したがって、あなたはIContextにアクセスできます。これは静的ではありません。
  • Getオーバーロード受け入れIParameter sです。これらはIContextに記載されています。セッションスコープ用のカスタムIParameter実装を作成できます。あなたのセッションをGetに渡す方法があります。

ただし、セッションIDとして整数を使用すると、おそらく動作しません。スコープオブジェクトは値型ではなく参照型でなければならないため、ボクシングが必要です。 Ninjectはこれを正しくサポートしていないかもしれません - 整数値の代わりに参照を比較する場合さらに、クリーンアップ(IDisposable.Dispose()呼び出し)は時期尚早に行われる可能性があります。 Ninjectはスコープの弱参照を保持します。スコープオブジェクトがINotifyWhenDisposedを実装していない場合、periodicallは弱参照が死んでいるかどうかをチェックします。死んだらリソースクリーンアップを行います。もちろん、ninjectが独自の "box"オブジェクトを取得し、そのオブジェクトに対して弱い参照しか保持しない場合、GCはいつでもこれを収集できます。スコープが実際に終了する前にリソースが処分される可能性があることを意味します。

スコープIDをオブジェクトにラップして(値だけでなくこのオブジェクトへの参照を保持する)、確定的なリソースクリーンアップのためにINotifyWhenDisposedを実装することをお勧めします。


ヒント:たぶんInCallScopeからNinject.Extensions.NamedScopeに含まれているが、あなたのユースケースのためのより良いフィット感だろう。

もう1つの可能な代替方法は、セッションごとにChildKernelを使用することです。それはセッションごとにカーネルを作成するのと似ていますが、それほど重くはありません。

+0

「静的フィールド」はちょうど頭字語/ショートカットでした。しかし、私はカスタムIPパラメータの実装にもっと興味を持っています。興味深いと思います。したがって、要するに、余分なパラメータ、ボックスセッションIDを提供することができます。これに基づいて新しいインスタンスまたは既存のインスタンスをどのように解決するかについて概要を教えてください。 InScope(x => x.Parameters.FirstOrDefault(p => p.Name == "SessionId"))のような意味ですか? 実際には、新しいIParameterを実装する必要はなく、Getを呼び出すときに提供するだけです。何かのようなものを得る(新しいパラメータ( "SessionId"、_currentBoxedSessionId));右? –

+0

@RadekStrugalskiあなたは本当にカスタムパラメータを必要としませんが、IMHOはちょっと洗濯機です。あなた次第。 "boxed session id" - いいえ、私はintフィールドを持つ 'Session'クラスを作成します。次に、このクラス/オブジェクトをアプリケーションで使用して、パラメータだけでなく、セッションを参照する必要があります。あなたがパラメータ内でそれを使うだけなら、誰もそれを参照している人はいなくて、あなたは "未定義の"振る舞いになります。 – BatteryBackupUnit

+0

@RadekStrugalskiあなたが[MCVE](https://stackoverflow.com/help/mcve)を提供しない限り、問題を解決するための模範的な実装を提供することは困難です。 – BatteryBackupUnit

関連する問題