我有一个 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 后执行遍历可视化树和注入的操作。
有一个更好的方法吗?也许是 Ninject 的 WPF 扩展,它可以让我做一个Get<GameWindow>()
,并自动为我遍历逻辑树(如 #4 所示),对所有内容进行属性注入?如果没有这样的东西,我可以写吗?
你们如何将 Ninject 与 WPF 一起使用?您是否使用上述任何方法(如果是,您能否分享我不知道的优点/缺点)?你有更好的方法吗?