【发布时间】:2015-12-09 16:51:30
【问题描述】:
尝试使用 MVVM 模式回填 WPF 应用程序以使用依赖注入。我对 DI 不太熟悉,之前只使用过一次,但我想我了解其中的原理。
我需要确保所有绑定都注册在一个地方 - 应用程序根目录。在 WPF 中,这是 OnStartup 方法。因此,我抓住了 Ninject 并将其放入我的应用程序中,以尝试将我的存储库类自动绑定到初始视图:
private void OnStartup(object sender, StartupEventArgs e)
{
IKernel kernel = new StandardKernel();
kernel.Bind<IRepository>().To<Repository>();
Views.MainView view = new Views.MainView();
view.DataContext = kernel.Get<ViewModels.MainViewModel>();
view.Show();
}
从现在开始,我使用数据模板资源设置上下文:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:My.Views"
xmlns:models="clr-namespace:My.ViewModels" >
<DataTemplate DataType="{x:Type models:MyViewModel}" >
<views:MyView />
</DataTemplate>
<!-- etc -->
</ResourceDictionary>
而且它有效。伟大的!但是,在 MainViewModel 中,我按下一个按钮并将不同类型的 ViewModel 加载到窗口中:
NavigationHelper.NewWindow(this, new QuoteViewModel(quote, new Repository()));
这行代码正是最初将我吸引到 DI 的原因——我无法对此进行测试,因为我无法在此处模拟依赖项。在这种情况下添加 DI 对我一点帮助都没有,因为我只应该在 OnStartUp 中使用我的 IoC 容器,所以我不能使用 kernel.Get 来获取我的 QuoteViewModel,对吧?
四处窥探所以我看到很多人建议我使用服务定位器解决这个问题。这对我来说是新的,而且我还看到很多人告诉我,将其用于 DI 是一种反模式,不应该与 bargepole 接触。谁是对的?
也许更重要的是,这个问题是否有一个巧妙的解决方案?我见过其他几个例子,它们需要不同软件包的大杂烩才能使其工作。现在,感觉 MVVM 和 DI 并不能很好地相互配合。
【问题讨论】:
标签: c# wpf mvvm dependency-injection inversion-of-control