现在的位置: 首页 > 综合 > 正文

深入 Unity 1.x 依赖注入容器之四:依赖注入

2011年06月27日 ⁄ 综合 ⁄ 共 2102字 ⁄ 字号 评论关闭

原文链接:http://www.doriandeng.cn/archives/100.html

 

Unity 是一个依赖注入容器,自然依赖注入是它最重要的功能。从以往的讨论来看,矛盾都集中于 Unity 侵入了依赖的对象,这可能是 Unity 在预览版的文档中没有说明,加上某个外国牛人的某篇文章造成的恶果。因为,Unity 同样可以通过配置文件支持非侵入式的依赖注入。本文将从使用 Attribute 和配置文件两个方面对 Unity 的依赖注入的支持进行阐述。

Unity 支持构造函数、属性和方法调用注入。

构造函数注入

构造函数注入包含了二种情况,一种是类仅有一个构造函数时,Unity 可以进行自动注入;另一种情况是,类包含多个构造函数时,必须使用 Attribute 或者配置文件指定注入时使用的构造函数。

假设现在有一个 Telephone 类,仅包含了一个带有 IDialer 类型的参数的构造函数。

如下所示:

那么,我们可以这样来使用:

此时,我们不需要对 Telephone 进行任何配置。

然后,再添加一个带有 string 类型参数的构造函数(注意,此构造函数没有实质用处),如下所示:

如果此时我们再使用上面示例中的代码,系统将会抛出 ResolutionFailedException 异常,因为此时 Unity 无法解析要使用哪个构造函数来生成对象,但是,如果其中有一个构造函数为默认构造函数时,Unity 会自动选择带参数的那一个构造函数。

此时,我们就需要为 Unity 指定将被使用的构造函数,方法是在将被使用的构造函数上加上 InjectionConstructor 特性。如下所示:

这样,Unity 又能正确的选择构造函数并创建新的对象了。

下面,再来看看使用配置文件来送到同样的效果。先在项目中添加一个应用程序配置文件,然后加入如下代码:

从上面中我们可以看到,依赖注入的配置是通过 typeConfig 元素来指定的,其子元素 constructor 指定了构造函数依赖注入,并且用元素 param 指出,将使用参数类型为 IDialer 的构造函数。另外,dependency 元素指定此参数的的值使用依赖注入,这样,Unity 就自动根据容器中注册的类型映射为构造函数来创建一个对象实例。Dependency 元素可以用 value 元素来代替以直接指定一个常量。

然后,需要将客户代码修改如下,以应用配置:

运行代码,我们将可以得到同样的结果。

属性注入(setter)

属性注入用于为目标对象的特定属性自动创建指定类型的值。

在前面的 Telephone 类中,有一个名为 Dialer 的 Dialer 类型的属性,Dialer 类是一个抽象类。Telephone 的 Dialer 属性如下图所示:

然后,我们用如下代码来使用它。(注意,代码中分别注册了二个类型映射,Dialer 和 IDialer,Telephone 的构造函数的参数为 IDailer 类型,而Dialer 属性的类型为 Dialer 抽象类):

运行上面的代码,我们可以得到下面的结果:

可能你已经发现,这并不是我们想要的结果,Dialer 类映射的类型应该是 ButtonTypeDialer 类,而不是结果中的 FigurePlateDialer 类型,也就是说,Unity 仅仅应用上了构造函数依赖注入,而没有应用属性注入,为什么呢?因为属性注入必须用特性或者配置文件指定,Unity 才会应用。

我们为 Telephone 的 Dialer 属性加上 Dependency 特性,如下所示:

再次运行上面的代码,我们就能看到输出的是 ButtonTypeDialer 了。注意,在这里,Unity 同时应用了构造函数注入和属性注入,为什么我们看到的结果是属性注入的结果呢?因为构造函数注入是在属性注入之前被应用的,如果没有创建对象,属性注入不 能应用到不存在的对象的属性上。

和构造函数注入一样,我们可以用配置文件来指定属性注入。在这可以通过在配置文件中的 typeConfig 元素中添加 property 元素来实现,如下所示:

注意,在此类型的指定使用的是 propertyType ,而不是构造函数中所使用的 parameterType。如果使用默认类型映射的话,dependency 元素也可以忽略,如果需要指定命名映射,则可以用 dependency 的 name 属性来指定。同时,dependency 元素也可以用 value 元素来代替。

运行如下代码,我们就可以得到期望的结果了:

方法调用注入

方法调用注入用于指示 Unity 在创建对象后,必须调用对象指定的方法,以执行指定的初始化等操作。

方法调用注入相对比较简单,如果使用 Attribute 的方式的话,就可以用 InjectionMethod 特性来标识方法,例如:

与之对应的配置文件如下所示:

是不是看起来很眼熟,对了,它其实与构造函数注入的配置差不多,唯一不同在于方法调用注入需要指定被调用的方法名称。

小结

Unity 同时支持构造函数注入、属性注入和方法调用注入,可以使用 Attribute 特性以侵入服务类的方式也可以使用配置文件以非侵入的方式来使用。

源代码下载

DependencyInjection.zip

希望对您有所帮助!

邓明

理想&美人

抱歉!评论已关闭.