传递MVVM中的服务

时间:2013-10-23 23:16:47

标签: c# wpf mvvm dependency-injection

我非常喜欢依赖注入的想法。我在应用这个概念时遇到了麻烦,因为我看到的大多数例子都是针对ASP.NET MVC的。

这是我得到的:WPF - >服务 - >库。服务获取注入的存储库,我的视图模型(至少有一个,无论如何)获得注入的服务。

然后在我的WPF App.xaml中,我重写了OnStartup方法。这是我创建Ninject并解析我的第一个视图的地方。

当谈到多个观点时,我迷路了。例如,假设我将ServiceA和ServiceB注入到我的第一个视图模型中(在App.xaml中)。让我们说一下我想在另一个视图模型的构造函数中使用ServiceC,如何将其注入到构造函数中?

在代码中说,就像这样:

public class ViewModel1
{
    private readonly IServiceA serviceA;
    private readonly IServiceB serviceB;

    public ViewModel1(IServiceA serviceA, IServiceB serviceB)
    {
        this.serviceA = serviceA;
        this.serviceB = serviceB;
    }

    public void OpenASettingsWindow()
    {
        // How do I resolve this view?
        var window = new View(new ViewModel2(new ServiceC()));
    }
}

2 个答案:

答案 0 :(得分:4)

您需要一个创建View实例的工厂。工厂构造函数将具有ServiceC参数。然后你需要将工厂注入ViewModel1。 以下代码基于您的代码。理想情况下,ViewModel1不需要了解View类的任何内容 - 它应该处理更为抽象的接口,例如IWhateverWindow,它们可以包含Show等方法。

public class ViewFactory
{
    private ServiceC _serviceC;

    public VewFactory(ServiceC serviceC)
    {
        _serviceC = serviceC;
    }

    public View CreateView()
    {
        return new View(new ViewModel(_serviceC));
    }
}

public class ViewModel1
{
    private readonly IServiceA serviceA;
    private readonly IServiceB serviceB;
    private ViewFactory _viewFactory;

    public ViewModel1(IServiceA serviceA, IServiceB serviceB, ViewFactory viewFactory)
    {
        this.serviceA = serviceA;
        this.serviceB = serviceB;
        _viewFactory = viewFactory;
    }

    public void OpenASettingsWindow()
    {
        // How do I resolve this view?
        var window = _viewFactory.CreateView();
    }
}

答案 1 :(得分:0)

直接在ViewModel的代码中创建View是对MVVM原则的主要违反。 ViewModels应该不知道Views。有许多方法可以以MVVM方式打开窗口。您可以在此answer中看到其中一些内容。