0

假设有使用 MVVM 轻工具包的 WPF 应用程序。

这个工具包的一个很好的例子是定位器。很棒的是它包含 SimpleIoC,它使我们能够注册服务并成为接口驱动。

有时 Locator 构造函数可以真正增长。不幸的是,除了注册接口之外,它还包含一些逻辑:

if(SimpleIoc.Default.GetInstance<MainViewModel>().LoadProject())
{
var project = SimpleIoc.Default.GetInstance<MainViewModel>().LoadedProject
SimpleIoc.Default.Register<ConfigService>(new Service(project))
}

这只是一个例子——如果我在定位器构造器中需要更多逻辑怎么办。也许我的服务架构是错误地创建的,因为它们不是独立的,或者在这种情况下,我应该放弃使用定位器 - 但是我会失去 DI。

另一件事是,在少数 ViewModel 中有对 Locator.GetInstance 的引用,我发现另一个不是一个好的做法,因为它应该通过构造函数注入以启用可测试性。

另一个方面是正确使用 AvalonDock。

AvalonDock 是一个很棒的可锚定控件,它可以准备应用程序,这些应用程序可能类似于具有可锚定、可停靠窗格的 Visual Studio 等应用程序。

这个窗格实际上是另一个通过属性绑定到 AvalonDock 的 ViewModel。

MainViewModel 具有属性 Tools = new Tools[] { ViewModel1, ViewModel2}

但是每个 ViewModel 都在 Locator 中注册。

因此我在 MainViewModel 中使用(违反 DRY)它们作为

属性获取器:Locator.GetInstance()

在我看来,这是另一个不好的例子——甚至不安全。如果 Avalon Tool ViewModel1 所需的任何服务尚未注册但在 MainViewModel 实例化期间通过 getter 调用,该怎么办。

开始不匹配了。你有什么好的做法吗?

我发现了许多示例,例如 Workspaces (MainViewModel),但没有人同时使用我发现非常有用的定位器。

我想保留 Locator,因为我认为它是一件好事,它使 mme 能够通过依赖注入和接口驱动来测试我的项目。

任何想法建议?我会很感激的。

4

1 回答 1

0

我会避免这种情况。正如您正确指出的那样,这里还有很多事情要做,而不是简单地注册类型。

相反,我会在其构造函数中将 ConfigService 实例传递给 Viewmodel。只要先注册,就可以IOC配置服务和视图模型。

SimpleIOC.Register<IViewModel>(()=>{return new ViewModel(SimpleIOC.GetInstance<IConfigService>())});

...这一切都来自记忆,所以可能不准确,但确实显示了 SimpleIOC 的自定义构造函数的想法。

然后,在您的视图模型构造函数中,您可以调用服务 .Register 方法,将自身作为参数传递。

这样可以将“知识”保留在您的视图模型中,并且您的定位器将专注于做它应该做的事情。

于 2014-10-19T07:51:15.963 回答