依存性を注入したいWPFUserControlがあります。Ninjectでこれを行うための最良の方法は何ですか?
具体的な例を挙げると、MapViewというUserControlがあり、コンストラクターまたはプロパティインジェクションを介してIDialogueServiceのインスタンスをインジェクトしたいと考えています。現在、依存性注入を使用しておらず、コントロールはXAMLで作成されています。
<Window x:Class="GameWindow" ...>
<Grid Name="root">
<MapView x:Name="mapView" ... />
<!-- other stuff here -->
</Grid>
</Window>
IKernelの作成、およびIDialogueServiceのバインドは、十分に簡単です。しかし、カーネルを使用して依存性をMapViewに注入する方法に固執しています。私はまだNinjectの初心者なので、何かが足りないのは明らかなことかもしれません。
私はこれを解決するためのいくつかの方法を考えることができます:
MapViewをコードでインスタンス化します。XAMLからを削除し、
<MapView ... />
代わりにこれをGameWindowのコンストラクターに追加します。public GameWindow(IKernel kernel) { root.Children.Add(kernel.Get<MapView>()); }
欠点:XAMLを使用しないことによる複雑さの増大。GameWindowはIKernelに依存しています。
XAMLでインスタンス化を維持し、代わりにプロパティインジェクションを使用します。
public GameWindow(IKernel kernel) { kernel.Inject(mapView); }
欠点:Ninjectのドキュメントには、Inject()は「ほとんどの場合に使用すべきではない」と書かれているため、私が思っていることを実行できるかどうか、またはここで使用するのが理にかなっているのかどうかさえわかりません。そして、GameWindowはまだIKernelに依存しています。
注入可能なパラメータ/プロパティをGameWindowに追加して、値をMapViewに渡します(おそらくMapViewのプロパティを介して)。次に、を使用します
Get<GameWindow>()
。欠点:現在、依存関係をあちこちに手動で渡しています。これは、DIフレームワークが自動化することになっているものです。ゲームウィンドウをインスタンス化した後、論理ツリーをたどり、すべてに対してIKernel.Inject()を呼び出します。欠点:繰り返しになりますが、Inject()が私が思うことを実行するかどうか、またはここで適切かどうかはわかりません。呼び出し元は、ゲームウィンドウをインスタンス化した後、視覚的なツリーをウォークアンドインジェクトすることを忘れないでください。
これを行うためのより良い方法はありますか?たぶん、NinjectのWPF拡張機能を使用するGet<GameWindow>()
と、論理ツリーを自動的にウォークして(#4のように)、すべてに対してプロパティインジェクションを実行できますか?そのようなものが存在しない場合、私はそれを書くことができますか?
NinjectとWPFを使用してどのようにアプローチしますか?上記のアプローチのいずれかを使用していますか(使用している場合は、私が知らない長所/短所を共有できますか)?より良いアプローチはありますか?