12

我有一个 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 的新手,所以也许我缺少一些明显的东西。

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

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

    public GameWindow(IKernel kernel) {
        root.Children.Add(kernel.Get<MapView>());
    }
    

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

  2. 将实例化保留在 XAML 中,并改用属性注入:

    public GameWindow(IKernel kernel) {
        kernel.Inject(mapView);
    }
    

    缺点:Ninject 文档说 Inject() “不应该在大多数情况下使用”,所以我什至不知道它是否做了我认为它做的事情,或者在这里使用它是否有意义。而且GameWindow仍然对IKernel有依赖。

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

  4. 实例化 GameWindow 后,遍历逻辑树并对所有内容调用 IKernel.Inject()。缺点:同样,我不知道 Inject() 是否按照我的想法做,或者在这里是否合适。调用者必须记住在实例化 GameWindow 后执行遍历可视化树和注入的操作。

有一个更好的方法吗?也许是 Ninject 的 WPF 扩展,它可以让我做一个Get<GameWindow>(),并自动为我遍历逻辑树(如 #4 所示),对所有内容进行属性注入?如果没有这样的东西,我可以写吗?

你们如何将 Ninject 与 WPF 一起使用?您是否使用上述任何方法(如果是,您能否分享我不知道的优点/缺点)?你有更好的方法吗?

4

1 回答 1

4

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

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

于 2009-07-20T05:20:44.563 回答