我有一个WPF用户控件,希望能够注入依赖项。使用Ninject最好的方法是什么?
以具体的例子来说:我有一个名为MapView的UserControl,我想通过构造函数或属性注入将我的IDialogueService实例注入到它中。目前,我没有使用任何依赖注入,并且我的控件是在XAML中创建的:
<Window x:Class="GameWindow" ...>
<Grid Name="root">
<MapView x:Name="mapView" ... />
<!-- other stuff here -->
</Grid>
</Window>
创建一个IKernel并绑定IDialogueService很简单,但我不知道如何使用这个kernel将依赖项注入到我的MapView中。我在Ninject方面还是个新手,可能我错过了一些明显的东西。我可以想到几种解决方法:
1. 在代码中实例化MapView。从XAML中移除 ``,并在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后进行遍历可视树和注入操作。
有更好的方法吗?也许有一个针对Ninject的WPF扩展,让我可以使用Get< GameWindow >(),并自动遍历逻辑树(就像#4中一样),在所有内容上进行属性注入?如果不存在这样的东西,我能否编写它?
你们如何处理在WPF中使用Ninject?您是否使用以上任何一种方法(如果使用,请分享我不知道的优缺点)?您是否有更好的方法?