首页 > 解决方案 > SimpleIoc.Default.GetInstance 的 MVVM Prism 转换是什么?

问题描述

我对 MVVM PPRISM 相当陌生,我正在重写一个使用 MVVMLight SimpleIOC 的项目。我在 MVVM Light 中注册时有以下代码行,我怀疑这是否是在 MVVM Prims 的 DryIOC 中转换它的正确方法。

SimpleIoc.Default.Register< iClassA, ClassA >();
SimpleIoc.Default.Register< iClassB, ClassB >();
// The factory method is necessary to prevent the linker from removing the class A constructor
SimpleIoc.Default.Register<IClassC>(() => new ClassC(SimpleIoc.Default.GetInstance<IClassA>(), SimpleIoc.Default.GetInstance<IClassB>()));

我的问题是containerRegistry.GetContainer().Resolve<IClassInterface>()正确的转换方式SimpleIoc.Default.GetInstance< IClassInterface >()

containerRegistry.Register<iClassA, ClassA>();
containerRegistry.Register<iClassB, ClassB>();
containerRegistry.RegisterInstance<ClassC>(new ClassC((iClassA)containerRegistry.GetContainer().Resolve<iClassA>(), (iClassB)containerRegistry.GetContainer().Resolve<iClassB >()));

标签: c#mvvmcontainersprismmvvm-light

解决方案


所以你在这里似乎有两个问题,所以我会尝试回答每个部分:

从 SimpleIoc 转换为 IContainerRegistry

我在 MVVM Light 中注册时有以下代码行,我怀疑这是否是在 MVVM Prims 的 DryIOC 中转换它的正确方法。

Prism 的 IContainerRegistry 是容器周围的抽象层,旨在保持绝大多数注册一致,无论您与 Prism 一起使用哪个 DI 容器。这也使得添加对不同容器的支持变得更容易,因为 Prism 已经概述了我们期望容器能够支持的接口。

例如,您有:

SimpleIoc.Default.Register<iClassA, ClassA>();

这在理论上将映射到等价物:

containerRegistry.Register<iClassA, ClassA>();

因为您正在处理一个抽象层,所以支持容器是 DryIoc、Unity 还是使用 SimpleIoc 的自定义实现并不重要。

现在,如果您需要访问某些特定于容器的 API,您可以随时调用GetContainer()扩展来访问底层容器(假设您使用的是 DryIoc 或 Unity)。

解析类型:

因此,如果您的容器有一个名为 Resolve 的方法返回类型,那么是的,您可以到容器中调用它,但更好的问题是您为什么要这样做?

我的问题是 containerRegistry.GetContainer().Resolve() 是从 SimpleIoc.Default.GetInstance() 转换的正确方法吗

如果您尝试从 IContainerRegistry 解决某些问题,因为您需要进行一些疯狂的初始化。我建议在您可能拥有的地方使用 DryIoc 的内置 API 之一:

containerRegistry.Register<IFoo, Foo>();
containerRegistry.GetContainer().Register<IBar>(Reuse.Singleton, 
       Made.Of(() => new BarImplementation("requiredString", Arg.Of<IFoo>()));

您会在这里注意到我故意忽略了您的 Rp1210 示例:

// The factory method is necessary to prevent the linker from removing the class A constructor
SimpleIoc.Default.Register<IClassC>(() => new Rp1210(SimpleIoc.Default.GetInstance<IClassA>(), SimpleIoc.Default.GetInstance<IClassB>()));

我忽略了这个有两个原因...

  1. 评论告诉我他们为什么这样做......链接器。关闭链接,或更新链接器配置以保留 IClassA 实现的 ctor。
  2. 使用 IoC 容器的全部意义在于它会自动理解它需要注入已注册的服务。

您会注意到我只引用了该容器特定的 API,因为它具有我需要注入的原始值。


推荐阅读