Unity容器依赖注入之属性注入使用备忘

by 独立观察员 | 2018年8月18日 16:37

容器之属性注入使用备忘

——独立观察员 2018.08.18[1]

最近在做我的毛坯项目"笔记扩展[2]",使用了的MVVM模式,使用了框架的一些功能,还没有使用功能,于是打算尝试一下。

框架官方支持Unity 和 MEF 两种 容器,也就是官方实现了这两种容器的初始化配置等,当然你也可以使用其他的容器,只不过需要自己配置而已。Unity是微软团队Practices开发的,目前已转为社区维护,代码托管于GitHub。

Unity容器支持三种依赖注入方式:构造器注入 (Constructor Injection)、属性注入 (Property Injection),以及方法调用注入 (Method Call Injection)。本文主要讨论属性注入方式。

本人认为,依赖注入的好处,除了老生常谈的方便切换依赖项的实现外,还有就是可以方便地传值,有点像是全局变量的感觉。当然,这一点应该是要设置容器内使用单例模式。本文主要展示这方面的用法,有不对的地方欢迎指正。

好了,废话少说,Let's go!

 

 

首先,新建一个模型类的接口和其默认实现:

 

然后我们打开Bootstrapper.cs文件,这个是Prism的启动类,可以通过让它继承哪个类,来决定使用哪个容器:

%title插图%num

这里我们继承的是UnityBootstrapper类,也就是说我们使用的是Unity容器。

 

UnityBoostrapper类做了很多初始化工作,其中,在ConfigureContainer方法中注册了很多类型,使用的是RegisterTypeIfMissing方法:

%title插图%num

 

所以,如果我们要注册自己的类型,就需要在Bootstrapper类中覆写ConfigureContainer方法:

同样使用 RegisterTypeIfMissing 方法,第一个参数传递接口类型,第二个参数传递实现类型,第三个参数指定是否使用单例模式。

 

下面来看看RegisterTypeIfMissing方法是怎样的:

%title插图%num

 

其中Container就是Unity的容器对象,如果不是使用Prism框架而是直接使用Unity的话,需要自己初始化这个对象。

然后其内部是使用Container的RegisterType方法来注册类型的。

 

 

注册好类型之后,我们就可以使用了。

属性注入的语法是使用Dependency特性,我们在ViewModel中添加一个属性:

然后就可以对该对象的属性进行赋值了,不需要创建该对象,因为容器会代劳的:

赋的值是什么不用管,其中第三行的方法中使用了这些值,在另一个类中。为什么舍近求远?只是为了测试。

 

 

上面提到的方法如下:

其中注释掉的部分我们称之为"方式一",未注释的部分自然就是"方式二"了。

 

通常是使用方式一的,只要像这样声明同样的依赖注入属性,就可以取得里面的值。但是这种方式有的时候会失效,比如这里的ModifyConfigModel就为null。听说是生命周期的原因,我也没有去深究,因为我们可以使用方式二。

 

方式二使用了ServiceLocator来获取实例,可以完美达到预期效果。

 

最后提一下,ServiceLocator 的命名空间为Microsoft.Practices.ServiceLocation,Unity的命名空间为Microsoft.Practices.Unity,感兴趣的朋友可以自行探索其中的异同点。

 

 

Source URL: http://dlgcy.com/unity-dependency/