分类:
2010-04-29 15:17:16
定义你的类的依赖是配置你程序的服务与动作的其中一个核心任务. 本章会介绍 Parsley 提供给你进行依赖注入的各种选项.
依赖注入的一般方式是使用 AS3 Metadata 标签方式. 因为一个类的依赖是该类的定义的一个重要方面,所以在 ActionScript 类本身进行依赖的定义最好不过. 在某些情况下你可能偏好于使用外部的依赖声明, 相关的选项会在本章的最后部分 进行讨论.
许多人会认为这是从封装方面来说最干净的注入, 因为它让你创建了不能改变的类. 由于 Flash Player 目前会忽略放在构造方法上的 metadata 标签,你需要将 [InjectConstructor]
标签放到类的声明上面来告诉 Parsley
产生构造器方式的注入:
package com.bookstore.actions {
[InjectConstructor]
class LoginAction {
private var service:LoginService;
private var manager:UserManager;
function LoginAction (service:LoginService, manager:UserManager = null) {
this.service = service;
this.manager = manager;
}
}
}
需要注意以上的例子中的 manager
参数是可选的. Parsley 会根据这个信息进行反射并决定依赖是必需的还是可选的.
所以在本例子中如果容器中没有LoginService 的话会抛出一个错误, 但没有CartService的话则不会..
构造器注入是基于参数类型进行注入. 这意味着容器中对于某个类型最多会包含一个对象. 你最好习惯于使用接口作为参数的类型,这样在改变接口的实现时就无需修改类的代码.
正如 所讲的,如果你想用构造器注入的话你不可以使用简单 MXML 标签来配置,因为该情况下 MXML 编译器会生成对象的创建代码并且 Parsley 只会在对象实例化后才能得到它. 所以不应该像下面那样定义一个类:
xmlns:mx=""
xmlns:actions="com.bookstore.actions.*">
你应该像下面那样来定义:
xmlns:mx=""
xmlns="">
import com.bookstore.actions.*;
]]>
在使用 Parsley 的 Object
标签时,对象是由容器来初始化的,这样构造器注入才可以实现.
使用 XML 配置时没有什么限制.
但 Flash Player 有个讨厌的 bug,就是在构造函数参数类型进行反射时使用的 describeType
并不能正确地工作 (这种情况下 Flash Player 总是把类型认为 '*'
).
解决这个 bug 的一个方法是在 Parsley 初始化前创建这些类的实例:
new LoginAction();
new ShoppingCartAction();
You can simply throw away these instances, just creating an instance "fixes" describe type for the parameter types of that class.
方法注入与构造器注入相似. 你可以将 [Inject]
metadata 标签放到任何方法上:
package com.bookstore.actions {
class LoginAction {
private var service:LoginService;
private var manager:UserManager;
[Inject]
public function init (service:LoginService, manager:UserManager = null) : void {
this.service = service;
this.manager = manager;
}
}
}
与构造器注入一样, Parsley 会知道方法的参数是可选的还是必需的并相应地将注入设定成可选的或必需的. 注入的对象会根据类型来选择,所以你需要确保你的配置中每种类型最多有一个对象. 方法注入的 MXML 配置并没有限制, 相比于构造器注入你只需使用简单 MXML 标签来往容器添加对象.
这种注入与方法注入相似, 用于属性的注入:
package com.bookstore.actions {
class LoginAction {
private var manager:UserManager;
[Inject]
public var service:LoginService;
[Inject(required="false")]
public function set manager (manager:UserManager) : void {
this.manager = manager;
}
}
}
你可以将 [Inject]
标签放到一个 var 声明或者一个 setter 方法上. 对于属性, Parsley 不能检测出该注入是必需的还是可选的,所以你要显性地设置它的 required
属性.
如果忽略该属性的话默认值是 true
.
像构造器注入和方法注入一样,这种注入也是根据类型注入的. 所以你需要确保你的配置中每种类型最多有一个对象.
如果你不想容器根据类型来注入,你可以显性地设置需要注入对象的 id 属性:
[Inject(id="defaultLoginService")]
public var service:LoginService;
这种情况下 Parsley 会根据 id 来注入,所以配置文件也需要包含一个对应的 id:
xmlns:mx=""
xmlns:actions="com.bookstore.services.*">
一般不推荐这种使用 id 的注入.最好使用根据类型来注入. 如果你需要显性地设置依赖的 id 的话,最好在像下一节那样的 MXML 或者 XML 中进行配置.
最后,你可以在 MXML 或者 XML 中声明依赖.
MXML 例子:
xmlns:mx=""
xmlns="">
import com.bookstore.actions.*;
import com.bookstore.services.*;
]]>
XML 例子:
xmlns="">
你可以见到 MXML 和 XML 配置几乎是一样的,细小的不同是标记的不同(capitalized camel-case vs. lower case names with dashes). 你可以为构造器的参数或者属性设置依赖. 对于构造器的参数你可以将它放到简单属性的标签里面:
3000
如果对象的属性是依赖于另一个对象的,应使用id-ref
属性指向那个对象而不是使用 value
属性.
在对象内容声明依赖
如果一个依赖只是被一对象使用的话,你可以在这个对象内部对它进行声明:
xmlns="">
内部对象的声明不可以设置其 id. MXML 的例子也是类似的.