After my recent explorations of “Swiz”, and “Spring ActionScript” (1,2,3), I decided to take the new version of the Parsley framework for a test drive, and build the Parsley version of inSync: the simple Contact Management application I often use to try out and demonstrate different features and techniques in Flex and Adobe AIR.

Parsley is primarily a Dependency Injection framework. It also offers a very interesting messaging infrastructure. I won’t get into the details of dependency injection here: My previous Swiz and Spring ActionScript articles provide some background information, and there are also plenty of detailed resources out there.
If you just want to run the application and dive into the code, here are the links:
Object Configuration
Parsley allows you to configure the core objects of your application (the objects other components depend on) in MXML (like Swiz), in XML (like Spring ActionScript), in ActionScript, or using any combination of these approaches. You can also extend the framework and create your own configuration mechanism.
For the inSync application, I used a simple MXML configuration (Config.mxml) defined as follows:
<?xml version="1.0" encoding="utf-8"?>
<Object xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:services="insync.parsley.services.*">
<mx:RemoteObject
id="contactRO"
destination="contacts"
endpoint="http://localhost:8400/samples/messagebroker/amf"
showBusyCursor="true" />
<services:ContactService />
</Object>
Note: In a real life application, you would not want to hardcode the endpoints of your services in your source code. You could use the XML configuration option to configure your endpoints in a more “externalized” fashion. More on this topic here.
Framework Initialization
You initialize the Parsley framework using the ContextBuilder class corresponding to the configuration approach you chose. Here is the main application file for the inSync application. Parsley is initialized in the preinitialize event of the application.
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:views="insync.parsley.views.*" paddingTop="0" paddingLeft="0" paddingRight="0" paddingBottom="0" preinitialize="FlexContextBuilder.build(Config)"> <mx:Script> <![CDATA[ import org.spicefactory.parsley.flex.FlexContextBuilder; ]]> </mx:Script> <mx:Style source="styles.css" /> <views:MainView /> </mx:Application>
Dependency Injection
Parsley supports constructor injection, method injection, and property injection (by type or by id).
In the following example (ContactForm.mxml), the framework will inject a specific implementation of the IContactService interface. In this case, the ContactService instance created in Config.mxml will be injected. This is an example of injection by type. Coding to the interface allows us to keep the view decoupled from a specific implementation of IContactService.
Note: Parsley doesn’t force you to use any specific design pattern. For simplicity in this sample application, I inject a service directly into the view. The use of an interface provides some level of decoupling, but you can of course use other patterns (like the Presentation Model) to achieve a greater level of abstraction. The Dependency Injection and Messaging infrastructure of Parsley will make the implementation of these patterns easier.
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
addedToStage="dispatchEvent(new Event('configureIOC', true))">
<mx:Script>
<![CDATA[
import insync.parsley.model.Contact;
import insync.parsley.services.IContactService;
[Inject]
public var service:IContactService;
[Bindable]
public var contact:Contact;
private function save():void
{
contact.firstName = firstName.text;
contact.lastName = lastName.text;
contact.email = email.text;
service.save(contact);
}
private function remove():void
{
service.remove(contact);
}
]]>
</mx:Script>
<mx:Form>
<mx:FormItem label="Id">
<mx:TextInput text="{contact.id}" enabled="false"/>
</mx:FormItem>
<mx:FormItem label="First Name">
<mx:TextInput id="firstName" text="{contact.firstName}"/>
</mx:FormItem>
<mx:FormItem label="Last Name">
<mx:TextInput id="lastName" text="{contact.lastName}"/>
</mx:FormItem>
<mx:FormItem label="Email">
<mx:TextInput id="email" text="{contact.email}"/>
</mx:FormItem>
</mx:Form>
<mx:HBox left="12" bottom="12">
<mx:Button label="Save" click="save()"/>
<mx:Button label="Delete" click="remove()"/>
</mx:HBox>
</mx:Canvas>
Note that in order to get its dependencies injected when it’s added to the stage, a view has to dispatch the “configureIOC” event.
Messaging
Parsley provides a generic Messaging infrastructure that allows you to exchange messages between objects in a decoupled, flexible, and easy-to-use manner:
- The event dispatcher and the event handler don’t know about each other.
- The event dispatcher and the event handler are decoupled from the framework: You dispatch events the Flex way.
Let’s look at the Search feature inSync as an example:
- The Toolbar class includes a simple TextInput that allows the user to specify a search criterion.
- The ContactList class displays the Search Results in a DataGrid.
The Toolbar class is defined as follows (non essential code removed for clarity):
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%"
addedToStage="dispatchEvent(new Event('configureIOC', true))">
<mx:Metadata>
[ManagedEvents("search")]
</mx:Metadata>
<mx:Script>
<![CDATA[
import insync.parsley.events.SearchEvent;
]]>
</mx:Script>
<mx:Label text="Search:" top="18" right="164"/>
<mx:TextInput id="searchBox" right="0" top="16"
change="dispatchEvent(new SearchEvent(SearchEvent.SEARCH, searchBox.text))"/>
</mx:Canvas>
Note that it dispatches a SearchEvent when the content of the search input field changes.
That event is defined as a managed event (using the ManagedEvents annotation), meaning that the framework will make sure that all the parties interested in that event will receive it.
How do you register as a listener for a managed event? You simply annotate a function with [MessageHandler], and it automatically becomes an event handler for that event, regardless of the display object hierarchy or whether the event bubbles or not.
Here is how it’s done in ContactList (non essential code removed for clarity):
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"
addedToStage="dispatchEvent(new Event('configureIOC', true))">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.collections.ArrayCollection;
import mx.rpc.events.FaultEvent;
import mx.rpc.AsyncToken;
import mx.rpc.AsyncResponder;
import mx.rpc.events.ResultEvent;
import insync.parsley.events.SearchEvent;
import insync.parsley.services.IContactService;
[Inject]
[Bindable]
public var service:IContactService;
[Bindable]
public var contacts:ArrayCollection;
[MessageHandler]
public function searchHanlder(event:SearchEvent):void
{
service.getContactsByName(searchStr).addResponder(new AsyncResponder(getContacts_result, faultHandler));
}
private function getContacts_result(event:ResultEvent, token:AsyncToken):void
{
contacts = event.result as ArrayCollection;
}
private function faultHandler(event:FaultEvent):void
{
Alert.show(event.fault.faultString);
}
]]>
</mx:Script>
<mx:DataGrid id="dg" dataProvider="{contacts}" width="100%" top="0" left="0" right="0" bottom="0"/>
</mx:Canvas>
With the simple [MessageHandler] annotation, the handler will be invoked every time an event of the function argument’s data type is dispatched in the application. If you need finer control, you can use the selector notation to specify the event type. For example in MainView.mxml, we register the contactDeleted function as a handler for the ContactEvent.DELETED event as follows.
[MessageHandler(selector="contactDeleted")]
public function contactDeletedHandler(event:ContactEvent):void
{
}
There is more to the Messaging capabilities of the Parsley framework. For example, you can use [MessageBinding] to bind a property of an object to the property of an event.
[MessageBinding(messageProperty="result",type=" mx.rpc.events.ResultEvent")] public var contacts:ArrayCollection;
Installation Instructions
- Download the project here
- Import it in Flex Builder
- Run the application. The application is configured to use the MockService (ContactServiceMock) by default, so it will run without any back-end.
If you want to use the Remoting service instead of the MockService:
- Replace <services:ContactServiceMock/> with <services:ContactServiceRemote/> in Config.mxml
- Install the BlazeDS turnkey server.
- Download insync-parsley-java.zip, and unzip it on your local file system.
- Copy classes/insync to blazeds/tomcat/webapps/samples/WEB-INF/classes/insync.
- Add the following destination to blazeds/tomcat/webapps/samples/WEB-INF/flex/remoting-config.xml:
- Copy insync/sampledb/insync to blazeds/sampledb/insync
- Edit server.properties in blazeds/sampledb, and modify the file as follows to add the insync database to the startup procedure.
server.database.0=file:flexdemodb/flexdemodb server.dbname.0=flexdemodb server.database.1=file:insync/insync server.dbname.1=insync server.port=9002 server.silent=true server.trace=false
- Start the database (startdb.bat or startdb.sh)
- Start BlazeDS
- Run the application
<destination id="contacts">
<properties>
<source>insync.dao.ContactDAO</source>
<scope>application</scope>
</properties>
</destination>


15 Comments
nice!
any reason it doesn’t include a “summary” section?
i got used to this little piece of subjective appreciation :)
supper flex examples mysql db
I like this function ver much
“Parsley provides a generic Messaging infrastructure that allows you to exchange messages between objects in a decoupled, flexible, and easy-to-use manner”
Very easy to learn with your example!
Thanks a lot :)
thanx very much
Having a bit of trouble importing to Flash Builder 4. I’ve tried several import methods to no avail.
Any suggestions, please.
I cant understand Parsley much, when will you use [inject],messageHandler and manageevents? im so confused..
Спасибо. было очень интересно.
Nice icons in the app. Would you mind if I ask where you got the icons? I guess I already asked.
I need a few good sources for free icons, as my design skills are not up to par.
Thanks,
Lee
Sorry for the last message. Let me answer my own question:
Those nice icons are available from:
http://www.famfamfam.com/
I realize now why the icons looked so familiar.
Lee
awesome example. really glad to finally read through it. Now I am looking forward to giving the framework a try. I really like the ManagedEvents and MangeHandler. This model is really close to a setup that I have used for a while on my own. I like the fact that it removes the need to write the addEventListener stuff in the class that needs to handle the event. Nice!
Hope you plan on more examples in the near term.
Rock On!
-Matthew
Very interesting site. Hope it will always be alive!,
Very nice example – just one suggestion to bring it up to date: Pam Beesly is now Pam Halpert :)
Thank you admin goood
[url=http://fyfk.ru/]анальное порно[/url]
4 Trackbacks
[...] 20/07/2009 Posted in 5584 by robertopriz on July 20, 2009 framwork http://coenraets.org/blog/2009/07/building-a-flex-application-with-the-parsley-framework/ [...]
[...] http://coenraets.org/blog/2009/07/building-a-flex-application-with-the-parsley-framework/ [...]
[...] for an example of building a Parsley based Flex application, have a look at this blog post by Christophe Coenraets alternatively have a look the documentation, Parsley is comprehensively documented: Parsley [...]
[...] http://coenraets.org/blog/2009/07/building-a-flex-application-with-the-parsley-framework/ [...]