はこのWith.ConstructorArgument
目的のために 1.0 に存在しました。2.0 では、構文がわずかに変更され
ました。- With.Parameters.ConstructorArgument with ninject 2.0
コンテキスト、プロバイダー、および引数を使用してこのようなものをより正確に渡す方法の詳細と例については、注入された依存関係に値を注入するを参照してください。
編集:スティーブンは私のコメントが無関係であるふりをすることを選択したので、いくつかの例(2.0の場合)で私が言っていることを明確にするのが最善です:
MyClass m = kernel.Get<MyClass>( new ConstructorArgument( "i", 2) );
私の目には非常に明確で、何が起こっているかを正確に述べています。
よりグローバルな方法でパラメーターを決定できる立場にある場合は、プロバイダーを登録して次のようにすることができます。
class MyClassProvider : SimpleProvider<MyClass>
{
protected override MyClass CreateInstance( IContext context )
{
return new MyClass( context.Kernel.Get<IService>(), CalculateINow() );
}
}
そして、次のように登録します。
x => x.Bind<MyClass>().ToProvider( new MyClassProvider() )
注意CalculateINow()
:ビットは、最初の回答のようにロジックを挿入する場所です。
または、次のようにもっと複雑にします。
class MyClassProviderCustom : SimpleProvider<MyClass>
{
readonly Func<int> _calculateINow;
public MyClassProviderCustom( Func<int> calculateINow )
{
_calculateINow = calculateINow;
}
protected override MyClass CreateInstance( IContext context )
{
return new MyClass( context.Kernel.Get<IService>(), _calculateINow() );
}
}
次のように登録します。
x => x.Bind<MyClass>().ToProvider( new MyClassProviderCustom( ( ) => new Random( ).Next( 9 ) ) )
更新: 上記よりもボイラープレートが少ない、大幅に改善されたパターンを示す新しいメカニズムがNinject.Extensions.Factory
拡張機能に
組み込まれています。https ://github.com/ninject/ninject.extensions.factory/wiki を参照してください。
前述のように、毎回異なるパラメーターを渡す必要があり、依存関係グラフに複数のレベルがある場合は、次のような操作が必要になる場合があります。
最後の考慮事項は、 a を指定していないUsing<Behavior>
ため、カーネルのオプション (サンプル内) で指定/デフォルト設定されているデフォルトにデフォルト設定されることです。これにより、ファクトリがオンザフライでTransientBehavior
計算するという事実が意味をなさない可能性があります[例:i
オブジェクトがキャッシュされていた場合]
ここで、FUD されて見過ごされているコメントの他のいくつかの点を明確にする必要があります。Ninject であれ、その他の目的であれ、DI を使用する際に考慮すべきいくつかの重要事項:
コンテナー固有の属性やトリックを使用する必要がないように、コンストラクター インジェクションによって可能な限り実行します。Your IoC Container is Showingと呼ばれる優れたブログ投稿があります。
コンテナーに移動して何かを要求するコードを最小限に抑えます。そうしないと、コードは a) 特定のコンテナー (CSL が最小化できる) b) プロジェクト全体のレイアウト方法に結び付けられます。CSLがあなたが思っていることをしていないことを示す良いブログ投稿があります. この一般的なトピックは、Service Location vs Dependency Injectionと呼ばれます。更新:詳細かつ完全な根拠については、 http: //blog.ploeh.dk/2011/07/28/CompositionRoot.aspxを参照してください。
statics と singleton の使用を最小限に抑える
[global] コンテナが 1 つしかなく、適切なグローバル変数のように必要なときにいつでも要求できると想定しないでください。複数のモジュールを正しく使用すると、Bind.ToProvider()
これを管理するための構造が得られます。そうすれば、それぞれの個別のサブシステムが独自に機能し、下位レベルのコンポーネントが上位レベルのコンポーネントなどに関連付けられることはありません。
誰かが私が参照しているブログへのリンクを記入したい場合は、それをいただければ幸いです (ただし、それらはすべて SO の他の投稿から既にリンクされているため、これはすべて複製 UI が目的で導入したものです)誤解を招く回答による混乱を避けるためです。)
さて、Joel が入ってきて、何がいい構文なのか、および/またはこれを行う正しい方法を本当に教えてくれたらいいのに!
更新:この回答は、獲得した賛成票の数から明らかに有用ですが、次の推奨事項を作成したいと思います。