使用Ninject将依赖项注入WPF

Joe*_*ite 12 wpf dependency-injection ninject

我有一个WPF UserControl,我想将依赖项注入其中.使用Ninject做到这一点的最佳方法是什么?

举一个具体的例子:我有一个名为MapView的UserControl,我想通过构造函数或属性注入将IDialogueService的实例注入其中.目前,我没有使用任何依赖注入,我的控件是在XAML中创建的:

<Window x:Class="GameWindow" ...>
    <Grid Name="root">
        <MapView x:Name="mapView" ... />
        <!-- other stuff here -->
    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

创建IKernel并绑定IDialogueService非常简单.但我坚持如何使用内核将依赖注入到我的MapView中.我仍然是Ninject的一个新手,所以也许有一些我很想念的东西.

我可以想到几种方法来解决这个问题:

  1. 在代码中实例化MapView.<MapView ... />从XAML中删除,然后将其添加到GameWindow的构造函数中:

    public GameWindow(IKernel kernel) {
        root.Children.Add(kernel.Get<MapView>());
    }
    
    Run Code Online (Sandbox Code Playgroud)

    缺点:不使用XAML会带来额外的复杂性; GameWindow依赖于IKernel.

  2. 保持XAML中的实例化,并使用属性注入:

    public GameWindow(IKernel kernel) {
        kernel.Inject(mapView);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    缺点:Ninject文档说Inject()"不应该用于大多数情况",所以我甚至不知道它是否符合我的想法,或者在这里使用它是否有意义.并且GameWindow仍然依赖于IKernel.

  3. 向GameWindow添加可注入参数/属性,将值传递给MapView(可能通过MapView上的属性),然后使用Get<GameWindow>().缺点:现在我手动传递依赖关系,这就是DI框架应该为我自动化.

  4. 在实例化GameWindow之后,遍历逻辑树并在所有内容上调用IKernel.Inject().缺点:再次,我不知道Inject()是否符合我的想法,或者它是否合适.调用者必须记住在实例化GameWindow之后执行walk-the-visual-tree-and-stuff.

有一个更好的方法吗?也许Ninject的WPF扩展允许我做一个Get<GameWindow>(),并为我自动遍历逻辑树(如#4),对所有内容进行属性注入?如果不存在这样的事情,我可以写出来吗?

你们如何在WPF中使用Ninject?你是否使用上述任何一种方法(如果是这样,你可以分享我不知道的情况)吗?你有更好的方法吗?

Ray*_*Ray 4

1)最好。您还会发现它是 Mapview 函数的便捷入口点。

另外,不需要传入内核,只需在 GameWindow 中执行 kernel.Get< GameWindow>() 和 [inject] MapView 即可。