wpf - 具有依赖关系的子 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 之间共享,而另一些则没有。我的问题是,我无法从组合根中注入它们。到目前为止,我只找到了两个解决方案:
- 有两个组合根(有点):解析 App.xaml.cs 中的 LoginViewModel 和 MainViewModel 以及 MainViewModel 中的子 ViewModel。这意味着,当使用 IOC 容器时,在两个类中都引用了该容器。
- 将子 ViewModel 作为 MainViewModel 的构造函数参数传递,并将它们视为任何其他依赖项。我对这种方法的问题是,如果我有十个 ViewModel,那么 MainViewModel 的构造函数会变得很大。
我读到可以将工厂传递给 MainViewModel 并将创建子 ViewModel 的责任委托给它,但我没有看到任何使用带有构造函数参数的子 ViewModel 的示例。
我不明白如何在不将所有子项的依赖项传递给 MainViewModel 的构造函数的情况下使用此方法,因此不会再次使其变得庞大。
也许有些东西我看不到,但对我来说似乎是死路一条。
请帮助我做对并告诉我正确的方向。
谢谢。
解决方案
直到现在我才意识到我把整个工厂的事情都弄错了。
实际上,我使用的 DI 容器 Ninject 有一个扩展,可以解决我遇到的完全相同的问题。此扩展需要一个接口,其中包含创建所需依赖项(在我的例子中为 ViewModel)并在幕后创建具体工厂的方法。我只是在滥用它,认为我需要以某种方式将所有依赖项传递给接口,同时它可以解析 ViewModel 本身,因为它们已经在容器中注册。
所以现在,我只有一个组合根(我的 App.xaml.cs),容器在其中解析 LoginViewModel 和 MainViewModel。后者将工厂接口作为依赖项,用于解析所有子 ViewModel,也由容器解析。不需要额外引用容器!
非常感谢 Coops 的帮助!你肯定让我在这里走上正轨!
推荐阅读
- ios - 如何修复文档警告 Xcode
- java - “动态 Web 项目”的问题 - Web 预览服务器未启动
- python - Matplotlib - 在数据帧 sublpot 中注释多行
- python - 在 PyCharm 社区中调试 Python 文件时出现 UnicodeDecodeError: 'utf-8'
- javascript - for循环中的时间比较
- google-apps-script - Google Apps 脚本在格式化 PDF 时出现问题
- azure - 权限不足,无法在 Azure Active Directory 中完成操作
- javascript - FeathersJs LEFT 加入另一个表(MongoDb)
- python - 使用 python 代码自动注册付款会引发错误
- netbeans - 即使我添加了 primefaces 5.0 库,Neatbeans 说“没有为命名空间 http://primefaces.org.ui 找到库”的原因是什么?