我试图在WPF MDI应用程序中同时使用MVVM和依赖注入模式。 我正在使用虚拟机优先方法。
基本上,我的应用程序从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's approach的启发,并使用SelectedViewModel属性来获取/设置当前使用的ViewModel,该ViewModel使用DataTemplates绑定到其View。我将让您查看该链接以获取有关该过程的更多详细信息,因为它与此处的问题完全无关。 重要的是我的MainViewModel负责在需要时切换ViewModel。但是我的孩子ViewModels具有依赖项。这是一个简化的示例:
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;
}
...
}
如您所见,有些子视图模型之间共享某些依赖项,而有些子视图模型之间则不共享。 我的问题是,我无法从合成根注入这些。到目前为止,我只找到了两种解决方案:
我读到有人可以将工厂传递给MainViewModel并委托创建子ViewModel的责任,但是我看不到任何使用带有构造函数参数的child ViewModel的示例。
我不明白如何在不将所有子项的依赖项传递给MainViewModel的构造函数的情况下使用该方法,因此又不会使其变得庞大。
也许我看不到某些东西,但这对我来说似乎是一个死路。
请帮助我解决这个问题,并告诉我正确的方向。
谢谢。
答案 0 :(得分:0)
直到现在我才意识到我把整个工厂的事情弄错了。
实际上,我使用的DI容器Ninject具有扩展名,可以解决我遇到的完全相同的问题。此扩展需要一个接口,该接口包含用于创建所需依赖关系(在本例中为ViewModels)并在幕后创建具体工厂的方法。我只是在滥用它,以为我需要以某种方式将所有依赖项传递给接口,同时它可以解析ViewModels本身,因为这些已经在容器中注册了。
现在,我所拥有的只是一个单一的组成根目录(我的App.xaml.cs),容器在其中解析LoginViewModel和MainViewModel。后者具有工厂接口作为依赖关系,用于解析所有子ViewModel,也由容器解析。无需额外引用容器!
非常感谢Coops的帮助!您一定会把我带到正确的轨道上!