本章对如何用Parsley构建一个简单的应用程序给出了一个非常快速的介绍,点击链接到手册中的其他地方查看更详细的说明。大多数都适用于相同的方式来构建Flex或Flash应用程序。只适用于Flex开发的例子会特别的指出说明。
2.1 Hello World
如果你想在阅读手册之前研究一个简单的例子,你可以在这里 找到一个Hello World,右键"View Source"查看源代码。
本节不会再提到该实例应用程序。
开始用Parsley开发首先你需要添加一些SWCs到你的classpath下。具体取决你要使用哪些特性,以及你是构建一个Flex还是Flash应用程序。更多查看 1.5 依赖性。
先下载Parsley Core 并从 release 和 相关的文件夹下添加所需要的SWCs 到你的 classpath下。你会在下载的Zip文件的release 文件夹下找到他们。
必须的SWCs
你始终需要:
· parsley-core-${version}.swc
· spicelib-commands-${version}.swc
· spicelib-reflect-${version}.swc
· spicelib-util-${version}.swc
Flex额外的SWC
对Flex来说还需要:
parsley-flex-${version}.swc
XML配置额外的SWCs
只有当使用XML配置的时候你才需要添加:
· parsley-xml-${version}.swc
· spicelib-xml-mapper-${version}.swc
这可能是Parsley使用最频繁的特性.。依赖关系可以用元数据,MXML,XML或者编程来配置。
使用 [Inject]元数据标签
你可以在属性上使用这个标签
[Inject]
public var loginService:LoginService;
[Inject]
public function set loginService (service:LoginService) : void {
或者你可以在方法上使用它一次声明多个依赖关系.
[Inject]
public function init (loginService:LoginService, cartService:CartService = null) : void{
上面的例子中有个好东西,那就是Parsley会反射参数类型并且会把可选参数当成可选依赖一样处理.所以这个例子如果没有LoginService会抛出一个错误, 但是如果容器中没有CartService 的话则会默默的忽略.
最后你还可以用一个相似的标签[InjectConstructor] 来进行构造方法注入,在类的声明上方,(因为Flex编译器会忽略构造方法上的元数据标签)。
[InjectConstructor]
public class LoginAction {
public function LoginAction (loginService:LoginService, cartService:CartService = null) : void {
同样的,因此第二个(可选的)参数将作为一个可选的依赖
最好的练习
我们在这节展示的所有例子的依赖关系将采用类。因为Parsley 会在属性和方法参数类型上进行反射。受益于一个IoC容器提供的松耦合,你应该更喜欢在注入点声明接口类型,这样你就可以在配置里切换实现而不接触需要这些服务的类的注入点。
当然,这仅适用于当你添加到容器的对象只有一个匹配这个类型的注入点。如果你同一个接口有多个实现,那么你需要通过id来切换注入,只有属性能使用id注入。
[Inject(id="mainLoginService")]
public var loginService:LoginService;
你自己决定选择使用属性、方法或构造函数注入。有些人喜欢使用构造函数注入,因为它通过更好的封装,允许你来创建不可变的类。但是只建议你在Flash Player 10.1或更新版本上使用构造函数注入,因为这之前的版本上构造函数有反射的BUG.
更多查看 4. 依赖注入
如果你用接口类型定义注入点,虽然依赖注入已经允许一定程度的解耦,但是有时候你会更喜欢你的程序某些部分甚至更松散的耦合,让应用程序的一部分通过消息进行通信,而发送方和接收对象不须了解彼此。
例如,你可能会改变底层视图事件去调用一个派发application 消息的表示层模型,所以,任何操作/控制器都可以用所有相关的消息类型注册。
关于这个话题更多查看 6 消息 和 11 构建MVC架构。
用Parsley你可以用元数据标签配置发送端和接受端。
发送部分可能仅仅包含一个[MessageDispatcher]标签在一个public function类型的属性上:
[MessageDispatcher]
public var dispatcher: Function;
public class LoginServiceImpl implements LoginService {
[...]
private function handleLoginResult (user:User) : void {
dispatcher(new LoginMessage(user));
}
}
在这里我们使用一个注入的dispatcher函数来发送一个LoginMessage的实例。用Parsley的 messages不需要去继承Event 类(尽管他们可以这样做,如果他们需要)。
接受端你可以用[MessageHandler] 标签来标签关联特定的消息类型。
[MessageHandler]
public function login (event:LoginEvent) : void {
像依赖注入通过类型来选择消息接收器,提高了系统的健壮性,因为你不用维护整个系统中唯一的事件类型字符串常量。
接收端有更多的标签,比如像[MessageBinding]标签,这些将会在 6 消息 中解释。
依赖注入和消息传递除了标签之外还有很多的配置选项。但是因为这些是非常常见的,我们现在将向你展示如何为IOC容器组装这些对象。在你给类添加元数据标签后,你必须告诉容器哪些对象应该管理。
Flex 应用程序
在Flex中你也许更喜欢使用MXML配置。你可以创建一个简单的MXML类(用Parsley命名空间的<Object> 作为根标签 ),然后添加所有你希望被Parsley 管理的类。
<Objects
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns="http://www.spicefactory.org/parsley"
xmlns:services="com.bookstore.services.*"
xmlns:actions="com.bookstore.actions.*">
<fx:Declarations>
<services:LoginServiceImpl timeout="3000"/>
<services:CartServiceImpl timeout="3000"/>
<actions:LoginAction/>
<actions:AddToCartAction/>
<actions:DeleteCartAction/>
</fx:Declarations>
</Objects>
当然你也可以用这个配置文件设置其他的属性值。他们与添加到容器中的类的元数据标签一起处理。
在这个例子中我们没有指定任何id属性。如果你只使用通过类注入,你不需要它们。如果你使用id注入,就像在最后一个示例的部分注入一样,你必须在这里指定它们。
<services:AdminLoginServiceImpl id="adminLogin" timeout="3000"/>
<services:UserLoginServiceImpl id="userService" timeout="3000"/>
你可以在注入点使用这些id:
[Inject(id="adminLogin")]
public var adminLogin:LoginService;
[Inject(id="userLogin")]
public var userLogin:LoginService;
但是一般来说你应该避免使用id注入,并且只在一个类有多个实例的情况下使用它。
Flash Applications
在这种情况下MXML是不可用的。所以首选配置机制可能是使用XML文件。 如果你不想把配置编译到你的应用程序中,当然你也可以使用外部XML文件。
一个示例XML配置相应的上面的MXML例子应该像这样:
<objects
xmlns="http://www.spicefactory.org/parsley"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.spicefactory.org/parsley
http://www.spicefactory.org/parsley/schema/2.3/parsley-core.xsd"
>
<object type="com.bookstore.services.LoginServiceImpl">
<property name="timeout" value="3000"/>
</object>
<object type="com.bookstore.services.CartServiceImpl">
<property name="timeout" value="3000"/>
</object>
<object type="com.bookstore.actions.LoginAction"/>
<object type="com.bookstore.actions.AddToCartAction"/>
<object type="com.bookstore.actions.DeleteCartAction"/>
</objects>
像MXML 例子一样我们不给对象定义指定ID。
你可以添加它如果你需要通过ID注入。
这些都是最常见的组装对象的选择。你会在 3 配置和初始化 找到更多的例子。
现在,你已经用元数据标签配置的类并且集合在MXML或XML里了,终于到初始化它的时间了。幸运的是,在大多数情况下,这是一行代码或一个简单的标签。
对于我们创建MXML配置文件,假设我们称之为 BookStoreConfig.mxml,标签应该像这样:
<parsley:ContextBuilder config="{BookStoreConfig}"/>
这就是所有的东西。
对于XML的例子,在一个Flash应用程序中我们必须以编程方式初始化上下文:
XmlContextBuilder.build("config.xml");
我们包含了最常见的用例在这里。这有很多选项,比如把配置分割为多个文件,甚至使用不同的配置机制(如在同一个应用程序使用MXML和XML)并把它们合并到一个上下文。这将在3.7组合多个配置机制 中演示。
对于模块化的应用程序,你不会想要把一切都打包成一个整体上下文,并且在应用程序开始加载所有这些东西。为构建模块化应用程序和根据需求加载和卸载配置,请查看 10构建模块化应用程序。
由于这是入门部分所以我们只包含了最常见的用例。但是希望它足够让你去解决简单的应用程序。你可能已经注意到手册是相当概括的,如果你认为你需要比包含在本章中更多的选项,你应该浏览余下的章节。
如果你只是想从Parsley的特性中得到一个想法,你可能想看 1.1特性列表.
最有趣的选项可能没有包括在这章:
3.6 配置 DSL 和 3.7 ActionScript配置 :你不必局限于用元数据,MXML或者XML配置,有两个更多的选择,这给你额外的灵活性。
6.7拦截消息:包含在这一章的一个MessageHandlers甚至允许你干扰信息调度过程(如暂停和恢复或取消消息处理)。
7 管理命令: 你可以用在他们执行的时候也被容器管理的方式来执行命令。
8.2 使用工厂:除了组装目标对象本身,还可以添加工厂到IOC容器创建对象,它在如何实例化的对象上给你额外的灵活性。
8.3异步对象初始化: 为异步地初始化对象配置选项(比如,对象需要加载数据才能操作)。在这种情况下,容器将延迟初始化其他的对象,直到这些配置已经为异步准备好了。
9动态视图装配: 我们已经简短的提到过这个。允许你连接定义在MXML中的Flex组件到声明的IOC容器中的对象上。
10 构建模块化应用程序:用一个配置上下文关联配置服务,操作,表示层模型等,可以根据需求加载和卸载。
12.1 资源绑定: 对于绑定属性的本地化资源的管理对象,当语言环境变化时自动更新。
13扩展框架:如果你想添加你自己的元数据,MXML或者XML配置标签或使用的其他一些可用的扩展点。用于简化重复配置任务或在Parsley之上创建框架。