我有一个wpf用户控件,我想将依赖项注入其中。最好的方法是什么
Ninject
?
举一个具体的例子:我有一个名为mapview的用户控件,我想通过构造函数或属性注入将IDialogueService的一个实例注入其中。目前,我没有使用任何依赖项注入,我的控件是在XAML中创建的:
<Window x:Class="GameWindow" ...>
<Grid Name="root">
<MapView x:Name="mapView" ... />
<!-- other stuff here -->
</Grid>
</Window>
创建一个ikernel,并绑定IDialogueService就足够简单了。但是我一直在研究如何使用内核将依赖项注入到我的mapview中。我在Ninject还是个新手,所以可能有一些明显的东西我找不到。
我可以想出几种方法来解决这个问题:
-
在代码中实例化mapview。移除
<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()是否做了我认为它做的事情,或者它在这里是否合适。调用方必须记住在实例化一个游戏窗口后执行漫游可视化树和注入操作。
有更好的方法吗?可能是Ninject的wpf扩展,它允许我执行
获取<GameWindow>()
,并自动为我遍历逻辑树(如4所示),对所有内容执行属性注入?如果这样的东西不存在,我能写下来吗?
你们如何使用Ninject和WPF?您是否使用上述任何一种方法(如果是,您是否可以分享我不知道的优点/缺点)?你有更好的方法吗?