我有一个WPF UserControl,我想将依赖项注入其中。使用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框架应该为我自动化。
在实例化GameWindow之后,遍历逻辑树并在所有内容上调用IKernel.Inject()。缺点:再次,我不知道Inject()是否符合我的想法,或者它是否合适。在实例化GameWindow之后,调用者必须记住执行walk-the-visual-tree-and-stuff。
有更好的方法吗?也许Ninject的WPF扩展允许我做Get<GameWindow>()
,并为我自动遍历逻辑树(如#4),对所有内容进行属性注入?如果这样的事情不存在,我可以写出来吗?
你们如何在WPF中使用Ninject?你是否使用上述任何一种方法(如果是这样,你可以分享我不知道的情况)吗?你有更好的方法吗?
答案 0 :(得分:4)
1)是最好的。您还会发现它是Mapview功能的便捷入口点。
另外,不要传入内核,只需要做kernel.Get&lt; GameWindow中的GameWindow&gt;()和[inject] MapView。