6

MVC 4 RC Web Api プロジェクトで Ninject 3 を使用するために以下のソリューションを使用しようとしたときに問題が発生しました。

http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/

このソリューションでは、IActivationBlock (IKernel の BeginBlock メソッドで作成) を使用して、呼び出しのスコープを実装します。通常の Ninject プロジェクトでは正常に動作しているように見えますが、プロジェクトが拡張機能 Ninject.Extensions.Interception.DynamicProxy を使用している場合、アクティベーション ブロックの Dispose メソッドが呼び出されると、次の例外が発生します。

Ninject コンポーネント IAdviceRegistry のロード中にエラーが発生しました

そのようなコンポーネントは、カーネルのコンポーネント コンテナーに登録されていません。

次に、新しい ActivationBlock が作成され、Resolve メソッドが呼び出されたときに、次の例外が発生します。

Ninject コンポーネント ICache のロード中にエラーが発生しました

そのようなコンポーネントは、カーネルのコンポーネント コンテナーに登録されていません。

この問題は MVC の更新に直接関係していないようですが、DynamicProxy と IActivationBlock の間に互換性がありません。

編集:

問題の原因は、型の 1 つがコンストラクターで IKernel を必要とし、DynamicProxy に直接関係していない場合ですが、最初の例外は、このアセンブリを参照する場合にのみ発生します。

そのため、タイプに IKernel が必要な場合は、2 番目のエラー (ICache に関連する) が常に発生します。

4

1 に答える 1

0

素晴らしい分析を要約すると、IKernel に直接依存する ActivationBlock 内にクラスのインスタンスを作成します。

これは論理的な欠陥です。ActivationBlock の考え方は、ブロックが破棄された後にカーネルの「状態を復元する」ことであり、インスタンスはカーネルにアクセスでき、バインディングのいずれかを元に戻すことができないように変更できるからです。(はい、インスタンスは、それ自体の後にクリーンアップする IDisposable である可能性があります。その場合、論理的な欠陥はありません。単なる珍しい使用例です)。

私の経験では、これらの使用の大部分は IKernel.Get<...>(...) とその友人を呼び出すことです。明らかに、これは ActivationBlock 内で有効です。必要以上のものを要求しているだけです: IResolutionRoot ではなく IKernel (たとえば、IKernel の IBindingRoot は必要ありません)。クラスの型を変更すれば問題ありません。

PS 例外の原因を分析していただきありがとうございます。それは私自身の問題で私を助けました。

于 2014-11-07T18:35:52.793 に答える