在我的视图模型中注入 Unity 容器

Unity container injection in my view models

我是 C# / .Net / Prism / WPF / DevExpress 的新手,开始在公司做一个大项目。由于我在项目中开始的有点晚,所以已经生成了很多代码,我经常偶然发现这样的代码:

public class AboutWindowViewModel : BindableBase
{
  public AboutWindowViewModel(IUnityContainer container)
  {
    ...

我发现"special"这里是容器中视图模型的依赖。在我目前查看的代码库中,它似乎是"pattern"。每个 class 都会在 IUnityContainer 中获得依赖关系,然后使用例如

手动解决依赖关系
container.ResolveEx<...>(...);

我习惯于使用其他语言的 DI 框架,所以这个例子对我来说只是胡说八道,因为它违背了 DI 框架的定义和它要解决的问题。例如,我试图编写一些代码来测试其中一个视图模型,结果证明这是一场噩梦。

现在,我向我公司的开发人员提出了这个问题,他们回答了我以下问题:

Prism recommendation is to resolve services using containers as they are needed.

因此,他们一直使用IUnityContainer.ResolveEx方法来解决它们。

我的问题是:这真的是推荐的使用 Prism 构建软件的方法吗???如果没有,您知道我在哪里可以找到通过示例清楚说明这一点的文档吗?

is that really the recommended way to build up software with Prism???

根本不是,因为它是一个 anti-pattern

Prism recommendation is to resolve services using containers as they are needed.

不只是 Prism,更一般地说,建议是让容器解析依赖项。当然,这可以通过手动调用 Resolve 来完成,但是这样做会破坏依赖注入所带来的所有好处。

相反,您想将依赖项列为构造函数参数并让容器填充它们。您的代码不需要 需要依赖于容器,除了entry-point ("resolution root")。应用程序应该只包含一个解析第一个实例的 Resolve 语句。

这是 Prism 发挥作用的地方:在您的 PrismApplication.RegisterTypesIModule.RegisterTypes 中,您可以配置您的容器。你告诉它哪种类型应该实现哪个接口。稍后,当需要视图模型时,Prism(准确地说是 ViewModelLocator)使用容器来解析视图模型,从而解决所有依赖项。没有理由让任何 class 依赖于容器,事实上,Prism 首先不会为 IContainerRegistry 注册任何东西。

请记住,容器不仅可以注入单例服务,还可以注入瞬态实例或工厂。如果您需要参数化工厂,您始终可以手动创建和注册复杂工厂。

在 side-note 上,我个人会犹豫是否为具有这样 code-base 的客户工作,因为这明显证明他们的开发人员不知道他们在做什么正在做。