我最近有机会创建一个新的基于棱镜的应用程序 . 我已经使用6.3版本了很长一段时间,但看到棱镜7已经退出预发行版并且想尝试一下 . 我使用棱镜模板包创建了一个新的棱镜应用程序,并且所有工作都按预期开箱即用 . 我更新了视图模型,就像通常在6.3中一样传入Container,这样我就可以解决一些稍后会向视图提供信息的对象,在6.3中我将执行以下操作:
public MainWindowViewModel(IRegionManager aRegionManager,
IUnityContainer aUnityContainer) : base()
现在在7.1.0.431中,我尝试做同样的事情,但更新了接口以考虑新的IOC抽象 .
public MainWindowViewModel(IRegionManager aRegionManager,
IContainerProvider aContainerProvider,
IContainerRegistry aContainerRegistry) : base()
这会从ViewModelLocator.AutoWireViewModel为IContainerX参数生成异常 .
System.Exception {Unity.Exceptions.ResolutionFailedException}
{"Resolution of the dependency failed, type = 'Sample.ViewModels.MainWindowViewModel', name = '(none)'.\nException occurred while: while resolving.\nException is: InvalidOperationException - The current type, Prism.Ioc.IContainerProvider, is an interface and cannot be constructed. Are you missing a type
这就像我缺少一个引用,但我将该类型传递给应用程序的RegisterTypes调用,因此应该找到所有引用 . 我是否为新的7.X版本做错了什么?
EDIT: Per @mnistic
以下是传递IContainerRegistry的App.xaml.cs提供的模板包中的代码 .
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//containerRegistry is a valid instance here
}
Update :
再深入研究一下,传入RegisterTypes的IContainerRegistry列出了调用该方法时可用的所有类型/接口 . 它注册了一个IUnityContainer实例 . 我在创建项目时为IOC选择了Unity,但我认为,可能不正确,IContainerRegistry正在隐藏客户端的实际实现 . 如果我更新ViewModel构造函数以接受IUnityContainer的对象,它会正确解析 .
public MainWindowViewModel(IRegionManager aRegionManager,
IUnityContainer aContainerProvider) : base()
这是理想的行为吗?
1 回答
不要这样做 . 你不希望容器在你的分辨率根之外,测试是可怕的,隐藏其他显而易见的依赖关系,并没有任何好处 .
如果您需要服务,请直接注入 . 如果您需要工厂,请注入
Func<IProduct>
或IHandcraftedFactory
. 如果您需要实现ISomething
的所有已注册类型,请注入ISomething[]
或IEnumerable<ISomething>
.示例(复杂)工厂与产品:
如果
Device
没有someParameter
,你会跳过IFactory
和DeviceFactory
并注入一个Func<IProduct>
......统一注意每个Device
然后接收IService
.记住 - 容器是为了简化事情:它解析依赖关系并创建实例和管理单例 . 但是如果你没有容器,一切都会正常工作,就像单元测试中的情况一样 . 您只需手动创建所有依赖项 .
回到手头的主题 -
IContainerRegistry
只是一个短暂的,薄的包装IUnityContainer
(在你的情况下),所以注册代码在使用不同容器的不同应用程序中看起来有些相似 . Prism试图通过不注册IContainerRegistry
来推动你朝着正确的方向前进(见上文),以便你在你应该使用它的地方使用它(在模块初始化期间)并阻止你在别处使用它(通过使它无法注入它) .