UnityContainer通过构造函数依赖注入的问题
来源:互联网 发布:战地4辅助淘宝 编辑:程序博客网 时间:2024/05/21 06:59
在使用Prism框架时,我们发现,Prism要求ViewModel对象在UnityContainer中注册时需要以object作为映射,并且由于Navigation的需要,ViewModel对象必须以命名的形式注册。
如下是符合Prism要求的注册方式:
unityContainer.RegisterType<object, ViewModelA>("ViewModelA");
有的场合,我们需要ViewModel作为单例存在,这是我们会在注册时加上生命周期管理:
unityContainer.RegisterType<object, ViewModelA>("ViewModelA", new ContainerControlledLifetimeManager());
这样能够保证ViewModelA在容器管理中不会多次构造,但事实真的如此吗?
假设有一个ViewModelB,其依赖于ViewModelA,所以我们在ViewModelB的构造函数中将ViewModelA注入:
public ViewModelB(ViewModelA viewModelA)
按照我们的设想,这里的ViewModelA应该是以单例的形式存在,于是我们通过如下程序来验证:
IUnityContainer unityContainer = new UnityContainer();unityContainer.RegisterType<object, ViewModelA>("ViewModelA", new ContainerControlledLifetimeManager());unityContainer.RegisterType<object, ViewModelB>("ViewModelB", new ContainerControlledLifetimeManager());Console.Out.WriteLine(1);unityContainer.Resolve(typeof (object), "ViewModelA");Console.Out.WriteLine(2);unityContainer.Resolve(typeof (object), "ViewModelA");Console.Out.WriteLine(3);unityContainer.Resolve(typeof (object), "ViewModelB");Console.Out.WriteLine(4);unityContainer.Resolve(typeof (object), "ViewModelB");
我们让A、B在构造函数中分别输出一句话,表示自己被构造了,运行的结果如下:
1ViewModelA Construct Id:023ViewModelA Construct Id:1ViewModelB Construct Id:04
第一次Resolve,VMA构造了,第二次Resolve,Unity直接取出了第一次构造的VMA,第三次Resolve时,Unity再次构造了VMA,并注入到VMB中,第四次Resolve取出VMB,这显然与我们的初衷不符。
为何Unity在注入时不去取之前已经构造的VMA呢?通过阅读Unity的源代码和一些实验我们终于了解到,Unity在构造函数注入时,会去找寻匿名的映射,而我们的ViewModelA是命名映射,所以并不会被Unity识别。
还是刚才那个程序,如果我们在RegisterType和Resolve时都不命名:
unityContainer.RegisterType<object, ViewModelA>(new ContainerControlledLifetimeManager());unityContainer.RegisterType<object, ViewModelB>(new ContainerControlledLifetimeManager());Console.Out.WriteLine(1);unityContainer.Resolve<ViewModelA>();Console.Out.WriteLine(2);unityContainer.Resolve<ViewModelA>();Console.Out.WriteLine(3);unityContainer.Resolve<ViewModelB>();Console.Out.WriteLine(4);unityContainer.Resolve<ViewModelB>();
那么结果将符合我们的预期:
1ViewModelA Construct Id:023ViewModelB Construct Id:04
但是由于Prism导航的缘故,我们不得不给ViewModel映射命名,所以我们的做法是:不在构造函数中注入任何命名映射对象,这类对象我们通过注入IUnityContainer来Resolve
这里不排除有其他更好的办法,我也是刚刚接触这个东西,如果有更好的办法请分享。
- UnityContainer通过构造函数依赖注入的问题
- c# UnityContainer 依赖注入的分析
- 如何理解java中的依赖注入 通过构造函数和反射机制来实现的
- 通过构造器注入IOC的依赖关系
- MVC | 依赖注入 AutoFac (构造函数注入)
- 控制反转(IOC)、依赖注入(DI)之通过构造函数注入简单属性
- 控制反转(IOC)、依赖注入(DI)之通过构造函数注入对象
- Spring通过构造方法依赖注入
- Spring_3_Spring的依赖注入_setter方法和构造函数方法
- Spring笔记之一:依赖注入的方式属性注入和构造函数注入
- Spring构造函数注入的问题
- Spring构造函数注入,无法注入的问题
- spring Ioc 依赖注入的三种方式:构造函数注入、setter方法注入和接口注入
- Ninject依赖注入——构造函数、属性、方法和字段的注入
- Ninject依赖注入——构造函数、属性、方法和字段的注入(三)
- 什么是构造函数注入(Constructor Injection)——一个具体的依赖注入例子
- Spring依赖属性注入和构造函数注入
- spring基于构造方法的依赖注入
- 史上最全的css hack(ie6-9,firefox,chrome,opera,safari)
- Java HashMap 分析四篇连载
- @property 属性介绍
- jQuery源码分析7: jQuery.trim
- 动窗口的制作暨CSizingControlBar类的使用说明
- UnityContainer通过构造函数依赖注入的问题
- Java调用存储过程
- HTC G系列 刷机流程
- java 正则表达式 字符必须全是 数字字母下滑线,或者第一个字符必须是字母数字下滑线
- 晴朗天
- [原创] Android SDK 安装全记录
- Java按自然月计算两个日期相差的年月日
- QA1:eclipse MAT hprof 文件无法打开
- [SQL,Java]判断某一个已知表名的表是否在数据库中存在的方法