首页 > 解决方案 > 具有依赖关系的子 ViewModel 的 WPF/MVVM 导航

问题描述

我试图在我的 WPF MDI 应用程序中同时使用 MVVM 和依赖注入模式。我正在使用 VM 第一种方法。

基本上,我的应用程序从 App.xaml.cs 类开始,如果我很好理解的话,它应该是我的组合根(所有依赖项都已解决)。这是一个示例:

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {          
            base.OnStartup(e);
            ...
            var login = new LoginView();
            login.DataContext = new LoginViewModel(Dependency1, Dependency2);
      
            loginView.ShowDialog();

            if (loginView.DialogResult.GetValueOrDefault())
            {
                 var app = new     MainWindow();
                 var mainVM = new MainViewModel(Dependency3, Dependency4);
                 app.DataContext = mainVM;
                 app.Show();
            }
        }
    }

到目前为止没问题,无论我是手动使用 DI 容器还是依赖注入,我都可以解决 LoginViewModel 和 MainViewModel 的依赖关系。现在让我们深入研究 MainViewModel。

我受到Rachel Lim 方法的启发,并使用 SelectedViewModel 属性来获取/设置当前使用的 ViewModel,该 ViewModel 使用 DataTemplates 绑定到其 View。我会让您查看链接以获取有关该过程的更多详细信息,因为它与我的问题完全无关。重要的是我的 MainViewModel 负责在需要时切换 ViewModel。但是我的孩子 ViewModel 有依赖关系。这是一个简化的示例:

     class MainViewModel
     {

            private ViewModel1 vm1;
            private ViewModel2 vm2;                

            public MainViewModel(Dependency1, Dependency2)
            {
                 ...
            }

            ...

            // Method used by an ICommand to display the ViewModel1's associated View
            private void DisplayView1() 
            {
                 vm1 = new ViewModel1(Dependency3, Dependency4, Dependency5);

            // Method used by an ICommand to display the ViewModel2's associated View
            private void DisplayView2() 
            {
                 vm2 = new ViewModel2(Dependency3, Dependency6);
                 SelectedViewModel = vm2;
            }
            ...
     }

如您所见,一些依赖关系在几个子 ViewModel 之间共享,而另一些则没有。我的问题是,我无法从组合根中注入它们。到目前为止,我只找到了两个解决方案:

我读到可以将工厂传递给 MainViewModel 并将创建子 ViewModel 的责任委托给它,但我没有看到任何使用带有构造函数参数的子 ViewModel 的示例。

我不明白如何在不将所有子项的依赖项传递给 MainViewModel 的构造函数的情况下使用此方法,因此不会再次使其变得庞大。

也许有些东西我看不到,但对我来说似乎是死路一条。

请帮助我做对并告诉我正确的方向。

谢谢。

标签: wpfmvvmdependency-injectionnavigationinversion-of-control

解决方案


直到现在我才意识到我把整个工厂的事情都弄错了。

实际上,我使用的 DI 容器 Ninject 有一个扩展,可以解决我遇到的完全相同的问题。此扩展需要一个接口,其中包含创建所需依赖项(在我的例子中为 ViewModel)并在幕后创建具体工厂的方法。我只是在滥用它,认为我需要以某种方式将所有依赖项传递给接口,同时它可以解析 ViewModel 本身,因为它们已经在容器中注册。

所以现在,我只有一个组合根(我的 App.xaml.cs),容器在其中解析 LoginViewModel 和 MainViewModel。后者将工厂接口作为依赖项,用于解析所有子 ViewModel,也由容器解析。不需要额外引用容器!

非常感谢 Coops 的帮助!你肯定让我在这里走上正轨!


推荐阅读