我有一个基于带有Caliburn.Micro和Ninject的MVVM的WPF应用程序。我有一个名为ShellViewModel的根 View 模型。它具有几个依赖项(通过构造函数注入(inject)),这些依赖项在Caliburn的Bootstrapper中进行配置。到目前为止,一切都很好。

在行的某个地方,有一个带有几个按钮的MenuViewModel,它们依次打开了具有自己依赖关系的其他 View 模型。这些 View 模型不是在创建根对象的过程中创建的,但是我仍然想从我的IoC容器中注入(inject)依赖关系。

我已经在service locator vs dependency injection上阅读了此问题,并且了解了要点。

但是我给我的印象是我的MenuViewModel需要能够访问我的IoC容器,以便正确注入(inject)动态创建的 View 模型。这是我要避免的事情。还有另一种方法吗?

最佳答案

是的,我相信您可以做得更好。

考虑一下,如果没有按需需求,那么显然可以使这些 View 模型成为MenuViewModel的依赖项,依此类推,直到到达对象图的根目录(ShellViewModel),然后容器将所有内容连接起来。

您可以通过将可以构造MenuViewModel依赖项的内容替换为依赖项本身,从而在对象图中放置“防火墙”。容器是这项工作的明显选择,从实际的角度来看,恕我直言,即使不是那么纯真的,这也是一个很好的解决方案。

但是您也可以用专用工厂代替容器。这个工厂将依赖容器,并为MenuViewModel的实际依赖项提供只读属性。访问属性将导致容器解析对象并返回它们(访问器方法也将代替属性起作用;更合适的是完全进行另一次讨论,因此仅使用您认为更好的方法即可)。

看起来您实际上并没有真正改变现状,但是如果MenuViewModel直接依赖容器,情况就不会一样了。在那种情况下,通过查看它的公共(public)接口(interface),您将不知道MenuViewModel的真正依赖性是什么,而现在您将看到对诸如

interface IMenuViewModelDependencyFactory
{
    public RealDependencyA { get; }
    public RealDependencyB { get; }
}

这是更多信息。而且,如果您查看具体MenuViewModelDependencyFactory的公共(public)接口(interface),也会发现更好:
class MenuViewModelDependencyFactory : IMenuViewModelDependencyFactory
{
    private Container container;

    public MenuViewModelDependencyFactory(Container container) { ... }

    public RealDependencyA { get { ... } }
    public RealDependencyB { get { ... } }
}

这里的MenuViewModelDependencyFactory打算对容器做什么是没有困惑的,因为它非常专业。

关于mvvm - 动态创建对象时避免控件反转的服务定位器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10473487/

10-11 04:16