最近在做我的毛坯项目”笔记扩展“,使用了WPF的MVVM模式,使用了Prism框架的一些功能,还没有使用依赖注入功能,于是打算尝试一下。
Prism框架官方支持Unity 和 MEF 两种 DI 容器,也就是官方实现了这两种容器的初始化配置等,当然你也可以使用其他的容器,只不过需要自己配置而已。Unity是微软团队Practices开发的,目前已转为社区维护,代码托管于GitHub。
Unity容器支持三种依赖注入方式:构造器注入 (Constructor Injection)、属性注入 (Property Injection),以及方法调用注入 (Method Call Injection)。本文主要讨论属性注入方式。
本人认为,依赖注入的好处,除了老生常谈的方便切换依赖项的实现外,还有就是可以方便地传值,有点像是全局变量的感觉。当然,这一点应该是要设置容器内使用单例模式。本文主要展示这方面的用法,有不对的地方欢迎指正。
好了,废话少说,Let’s go!
1、建立模型
首先,新建一个模型类的接口和其默认实现:
namespace Note.Models { public interface IModifyConfigModel { string Key { get; set; } string Value { get; set; } } public class ModifyConfigModel : IModifyConfigModel { public string Key { get; set; } public string Value { get; set; } } }
2、注册类型
然后我们打开Bootstrapper.cs文件,这个是Prism的启动类,可以通过让它继承哪个类,来决定使用哪个容器:
这里我们继承的是UnityBootstrapper类,也就是说我们使用的是Unity容器。
UnityBoostrapper类做了很多初始化工作,其中,在ConfigureContainer方法中注册了很多类型,使用的是RegisterTypeIfMissing方法:
所以,如果我们要注册自己的类型,就需要在Bootstrapper类中覆写ConfigureContainer方法:
protected override void ConfigureContainer() { base.ConfigureContainer(); RegisterTypeIfMissing(typeof(IModifyConfigModel), typeof(ModifyConfigModel), true); }
同样使用 RegisterTypeIfMissing 方法,第一个参数传递接口类型,第二个参数传递实现类型,第三个参数指定是否使用单例模式。
下面来看看RegisterTypeIfMissing方法是怎样的:
其中Container就是Unity的容器对象,如果不是使用Prism框架而是直接使用Unity的话,需要自己初始化这个对象。
然后其内部是使用Container的RegisterType方法来注册类型的。
3、存数据
注册好类型之后,我们就可以使用了。
属性注入的语法是使用Dependency特性,我们在ViewModel中添加一个属性:
[Dependency] public IModifyConfigModel ModifyConfigModel { get; set; }
然后就可以对该对象的属性进行赋值了,不需要创建该对象,因为容器会代劳的:
ModifyConfigModel.Key = nameof(DbPath); ModifyConfigModel.Value = DbPath; ConfigManager.SetValueTestIoc();
赋的值是什么不用管,其中第三行的方法中使用了这些值,在另一个类中。为什么舍近求远?只是为了测试。
4、取数据
上面提到的方法如下:
//[Dependency] //public static IModifyConfigModel ModifyConfigModel { get; set; } public static bool SetValueTestIoc() { //return SetValue(ModifyConfigModel.Key, ModifyConfigModel.Value); IModifyConfigModel modifyConfigModel = ServiceLocator.Current.GetInstance<IModifyConfigModel>(); return SetValue(modifyConfigModel.Key, modifyConfigModel.Value); }
其中注释掉的部分我们称之为”方式一”,未注释的部分自然就是”方式二”了。
通常是使用方式一的,只要像这样声明同样的依赖注入属性,就可以取得里面的值。但是这种方式有的时候会失效,比如这里的ModifyConfigModel就为null。听说是生命周期的原因,我也没有去深究,因为我们可以使用方式二。
方式二使用了ServiceLocator来获取实例,可以完美达到预期效果。
最后提一下,ServiceLocator 的命名空间为Microsoft.Practices.ServiceLocation,Unity的命名空间为Microsoft.Practices.Unity,感兴趣的朋友可以自行探索其中的异同点。
5、参考
(1)《Microsoft.Practices.Unity 入门 – 在 delphi 路上 – 博客园》
(2)《Prism 5 程序初始化过程 – Andy Ho – 博客园》
原创文章,转载请注明: 转载自 独立观察员(dlgcy.com)
本文链接地址: [Unity容器依赖注入之属性注入使用备忘](https://dlgcy.com/unity-dependency/)
关注微信公众号 独立观察员博客(DLGCY_BLOG) 第一时间获取最新文章
4条评论