<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Christophe Coenraets &#187; Frameworks</title>
	<atom:link href="http://coenraets.org/blog/category/frameworks/feed/" rel="self" type="application/rss+xml" />
	<link>http://coenraets.org/blog</link>
	<description>Rich Internet Applications, Flex, AIR, Java, Android</description>
	<lastBuildDate>Fri, 23 Jul 2010 14:45:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>MAX Frameworks Session: One Application, Four Implementations (Code Available)</title>
		<link>http://coenraets.org/blog/2009/10/max-frameworks-session-one-application-four-implementations-code-available/</link>
		<comments>http://coenraets.org/blog/2009/10/max-frameworks-session-one-application-four-implementations-code-available/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 16:27:18 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Frameworks]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=188</guid>
		<description><![CDATA[This year at MAX, I organized a “Flex Frameworks” session called “Using Flex Frameworks to build Data Driven Applications”. I wanted to stay away from a high level / rhetorical debate or panel. I also did not want a session aimed at proclaiming a (subjective) winner. What I had in mind was a pragmatic session [...]]]></description>
			<content:encoded><![CDATA[<p>This year at MAX, I organized a “Flex Frameworks” session called “Using Flex Frameworks to build Data Driven Applications”.  I wanted to stay away from a high level / rhetorical debate or panel. I also did not want a session aimed at proclaiming a (subjective) winner. What I had in mind was a pragmatic session that would provide developers with the information they need to make their own decision based on their background, the type of applications they build, and their own style and preferences. </p>
<p>To achieve this goal, I thought it would be interesting for the audience to look at the exact same application built with four different frameworks. And to avoid any misrepresentation of the frameworks, I asked the framework creators to build their own version of the application. Laura Arguello (<a href="http://mate.asfusion.com/">Mate</a>), Chris Scott (<a href="http://code.google.com/p/swizframework/">Swiz</a>), Alex Uhlmann (<a href="http://opensource.adobe.com/wiki/display/cairngorm">Cairngorm</a>), and Javier Julio (<a href="http://puremvc.org/">PureMVC</a>, standing in for Cliff Hall) accepted to take part in the experiment and implemented their own version of the “framework-less” application I provided them with. (Many thanks to all of them for the time and energy they put in the project!)</p>
<p>The end result was a three hours session where each of them presented their version. The session format wasn’t perfect: Three hours was too short to get the attendees to actually build the application using four different frameworks, but it was probably also a little too long to look at and decipher code written by someone else. But in the end I think the information that was provided and the applications the attendees left with were really useful for anybody looking at making a framework decision.</p>
<h3>Download</h3>
<p>I thought these applications would also be helpful to you if you didn’t attend the session…You can download the code <a href="http://coenraets.org/flex-frameworks/flex-frameworks-max.zip">here</a> and read the Getting Started instructions <a href="http://coenraets.org/flex-frameworks/Getting-Started.pdf">here</a>. </p>
<p>Notes: </p>
<ul>
<li>The &#8220;plain&#8221; project is the framework-less version of the application.</li>
<li>Do not unzip flex-frameworks-max.zip in a directory path that includes white spaces.</li>
<li>You will notice that there may be different projects for a single framework. This is because there is sometimes a conflict between apparent simplicity and real abstraction, and I wanted to make sure the framework creators would be able to show different ways to use their framework.</li>
</ul>
<h3>What’s wrong with the plain version?</h3>
<p>The implementation of the plain (framework-less) version is intentionally simplistic. Components are tightly coupled (for example, views are tightly coupled to specific types of services); the responsibility of components overlap (poor implementation of the “separation of concerns” concept); the configuration/initialization of components is not externalized; there is no clear messaging scheme in the application, which in turns leads to tight coupling, etc. These are some of the things to look at, when you examine a specific framework implementation of the application.</p>
<h3>More Information</h3>
<p>Laura posted her presentation <a href="http://mate.asfusion.com/assets/content/presentations/mate_max_2009.pdf">here</a>.<br />
Javier posted his presentation <a href="http://www.javier-julio.com/presentations/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2009/10/max-frameworks-session-one-application-four-implementations-code-available/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Don’t miss the “Flex Frameworks” session at MAX</title>
		<link>http://coenraets.org/blog/2009/08/don%e2%80%99t-miss-the-%e2%80%9cflex-frameworks%e2%80%9d-session-at-max/</link>
		<comments>http://coenraets.org/blog/2009/08/don%e2%80%99t-miss-the-%e2%80%9cflex-frameworks%e2%80%9d-session-at-max/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 15:23:26 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[MAX2009]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=124</guid>
		<description><![CDATA[I’ve been working on putting together what should be a fun and informative session at MAX this year. The session is called: “Using Flex Frameworks to Build Data-Driven Applications”. This is a 3 hour BYOL (Bring Your Own Laptop) session. The idea is to look at four versions of the exact same application: each version [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been working on putting together what should be a fun and informative session at <a href="http://max.adobe.com/">MAX</a> this year. The session is called: “Using Flex Frameworks to Build Data-Driven Applications”.</p>
<p>This is a 3 hour BYOL (Bring Your Own Laptop) session. The idea is to look at four versions of the exact same application: each version built with a different framework by a framework founder or expert: <a href="http://www.asfusion.com/blog/">Laura Arguello</a> for <a href="http://mate.asfusion.com/">Mate</a>, <a href="http://cdscott.blogspot.com/">Chris Scott</a> for <a href="http://code.google.com/p/swizframework/">Swiz</a>, <a href="http://www.javier-julio.com/blog/">Javier Julio</a> for <a href="http://puremvc.org/">PureMVC</a>, and <a href="http://blogs.adobe.com/auhlmann/">Alex Uhlmann</a> for <a href="http://opensource.adobe.com/wiki/display/cairngorm/Cairngorm">Cairngorm</a>.</p>
<p>Each of them will have 45 minutes to walk you through the code and highlight the details of their implementation.  The goal of the session is not to declare a winner, but rather to compare different solutions to the same problem, and for you to identify the framework that fits your application requirements and your style.</p>
<p>The session is described <a href="http://max.adobe.com/scheduler/#view=1;session=314f672b-dddd-4564-bf49-43bb9a946c46">here</a> in the Adobe MAX session catalog.</p>
<p>I hope to see you there. This should be a great session!</p>
<p><a href="http://www.spicefactory.org/parsley/">Parsley 2</a> was released too late to make the initial line up, but I’m trying to find a way to include a Parsley version of the application in the session materials as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2009/08/don%e2%80%99t-miss-the-%e2%80%9cflex-frameworks%e2%80%9d-session-at-max/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Building a Flex Application with the Parsley Framework</title>
		<link>http://coenraets.org/blog/2009/07/building-a-flex-application-with-the-parsley-framework/</link>
		<comments>http://coenraets.org/blog/2009/07/building-a-flex-application-with-the-parsley-framework/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 20:47:24 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Parsley]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=122</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>After my recent explorations of “<a href="http://coenraets.org/blog/2009/02/sample-application-using-the-swiz-framework-and-blazeds/">Swiz</a>”, and “Spring ActionScript” (<a href="http://coenraets.org/blog/2009/03/the-%E2%80%9Cspring-actionscript%E2%80%9D-framework-%E2%80%93-part-1-the-basics/">1</a>,<a href="http://coenraets.org/blog/2009/03/the-spring-actionscript-framework-%E2%80%93-part-2-autowiring/">2</a>,<a href="http://coenraets.org/blog/2009/03/the-spring-actionscript-framework-part-3-injecting-services-and-mock-services/">3</a>), I decided to take the new version of the <a href="http://www.spicefactory.org">Parsley framework</a> 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.</p>
<p><img src="http://coenraets.org/apps/insyncparsley/parsley.png"/></p>
<p>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.</p>
<p>If you just want to run the application and dive into the code, here are the links:</p>
<ul>
<li>Click <a href="http://www.coenraets.org/apps/insyncparsley/main.html">here</a> to run the application.</li>
<li>Click <a href="http://www.coenraets.org/apps/insyncparsley/srcview/index.html">here</a> to view the source code.</li>
</ul>
<h2>Object Configuration</h2>
<p>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.</p>
<p>For the inSync application, I used a simple MXML configuration (Config.mxml) defined as follows:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;Object xmlns=&quot;*&quot; xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; xmlns:services=&quot;insync.parsley.services.*&quot;&gt;

    &lt;mx:RemoteObject
            id=&quot;contactRO&quot;
            destination=&quot;contacts&quot;
            endpoint=&quot;http://localhost:8400/samples/messagebroker/amf&quot;
            showBusyCursor=&quot;true&quot; /&gt;

    &lt;services:ContactService /&gt;

&lt;/Object&gt;
</pre>
<p>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 <a href="http://coenraets.org/blog/2009/03/externalizing-service-configuration-using-blazeds-and-lcds/">here</a>.</p>
<h2>Framework Initialization</h2>
<p>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.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; xmlns:views=&quot;insync.parsley.views.*&quot;
	paddingTop=&quot;0&quot; paddingLeft=&quot;0&quot; paddingRight=&quot;0&quot; paddingBottom=&quot;0&quot;
	preinitialize=&quot;FlexContextBuilder.build(Config)&quot;&gt;

	&lt;mx:Script&gt;
		&lt;![CDATA[
			import org.spicefactory.parsley.flex.FlexContextBuilder;
		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:Style source=&quot;styles.css&quot; /&gt;

	&lt;views:MainView /&gt;

&lt;/mx:Application&gt;
</pre>
<p><span id="more-122"></span></p>
<h2>Dependency Injection</h2>
<p>Parsley supports constructor injection, method injection, and property injection (by type or by id).</p>
<p>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.</p>
<p>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.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Canvas xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
	addedToStage=&quot;dispatchEvent(new Event('configureIOC', true))&quot;&gt;

	&lt;mx:Script&gt;
		&lt;![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);
		}

		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:Form&gt;
		&lt;mx:FormItem label=&quot;Id&quot;&gt;
			&lt;mx:TextInput text=&quot;{contact.id}&quot; enabled=&quot;false&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem label=&quot;First Name&quot;&gt;
			&lt;mx:TextInput id=&quot;firstName&quot; text=&quot;{contact.firstName}&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem label=&quot;Last Name&quot;&gt;
			&lt;mx:TextInput id=&quot;lastName&quot; text=&quot;{contact.lastName}&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem label=&quot;Email&quot;&gt;
			&lt;mx:TextInput id=&quot;email&quot; text=&quot;{contact.email}&quot;/&gt;
		&lt;/mx:FormItem&gt;
	&lt;/mx:Form&gt;

	&lt;mx:HBox left=&quot;12&quot; bottom=&quot;12&quot;&gt;
		&lt;mx:Button label=&quot;Save&quot; click=&quot;save()&quot;/&gt;
		&lt;mx:Button label=&quot;Delete&quot; click=&quot;remove()&quot;/&gt;
	&lt;/mx:HBox&gt;

&lt;/mx:Canvas&gt;
</pre>
<p>Note that in order to get its dependencies injected when it’s added to the stage, a view has to dispatch the “configureIOC” event.</p>
<h2>Messaging</h2>
<p>Parsley provides a generic Messaging infrastructure that allows you to exchange messages between objects in a decoupled, flexible, and easy-to-use manner:</p>
<ul>
<li>The event dispatcher and the event handler don’t know about each other.</li>
<li>The event dispatcher and the event handler are decoupled from the framework: You dispatch events the Flex way.</li>
</ul>
<p>Let’s look at the Search feature inSync as an example:</p>
<ul>
<li>The Toolbar class includes a simple TextInput that allows the user to specify a search criterion.</li>
<li>The ContactList class displays the Search Results in a DataGrid.</li>
</ul>
<p>The Toolbar class is defined as follows (non essential code removed for clarity):</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Canvas xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; width=&quot;100%&quot;
	addedToStage=&quot;dispatchEvent(new Event('configureIOC', true))&quot;&gt;

	&lt;mx:Metadata&gt;
		[ManagedEvents(&quot;search&quot;)]
	&lt;/mx:Metadata&gt;

	&lt;mx:Script&gt;
		&lt;![CDATA[
			import insync.parsley.events.SearchEvent;
		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:Label text=&quot;Search:&quot; top=&quot;18&quot; right=&quot;164&quot;/&gt;

	&lt;mx:TextInput id=&quot;searchBox&quot; right=&quot;0&quot; top=&quot;16&quot;
		change=&quot;dispatchEvent(new SearchEvent(SearchEvent.SEARCH, searchBox.text))&quot;/&gt;

&lt;/mx:Canvas&gt;
</pre>
<p>Note that it dispatches a SearchEvent when the content of the search input field changes.</p>
<p>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.</p>
<p>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.</p>
<p>Here is how it&#8217;s done in ContactList (non essential code removed for clarity):</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Canvas xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; width=&quot;100%&quot; height=&quot;100%&quot;
	addedToStage=&quot;dispatchEvent(new Event('configureIOC', true))&quot;&gt;

	&lt;mx:Script&gt;
		&lt;![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);
			}		

		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:DataGrid id=&quot;dg&quot; dataProvider=&quot;{contacts}&quot; width=&quot;100%&quot; top=&quot;0&quot; left=&quot;0&quot; right=&quot;0&quot; bottom=&quot;0&quot;/&gt;

&lt;/mx:Canvas&gt;
</pre>
<p>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.</p>
<pre class="brush: jscript;">
[MessageHandler(selector=&quot;contactDeleted&quot;)]
public function contactDeletedHandler(event:ContactEvent):void
{
}
</pre>
<p>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.</p>
<pre class="brush: jscript;">
[MessageBinding(messageProperty=&quot;result&quot;,type=&quot; mx.rpc.events.ResultEvent&quot;)]
public var contacts:ArrayCollection;
</pre>
<h2>Installation Instructions</h2>
<ol>
<li>Download the project <a href="http://www.coenraets.org/apps/insyncparsley/srcview/insync-parsley.zip">here</a></li>
<li>Import it in Flex Builder</li>
<li>Run the application. The application is configured to use the MockService (ContactServiceMock) by default, so it will run without any back-end.</li>
</ol>
<p>If you want to use the Remoting service instead of the MockService:</p>
<ol>
<li>Replace &lt;services:ContactServiceMock/&gt; with &lt;services:ContactServiceRemote/&gt; in Config.mxml</li>
<li>Install the <a href="http://opensource.adobe.com/blazeds">BlazeDS turnkey server</a>.</li>
<li>Download <a href="http://coenraets.org/apps/insyncparsley/insync-parsley-java.zip">insync-parsley-java.zip</a>, and unzip it on your local file system.</li>
<li>Copy classes/insync to blazeds/tomcat/webapps/samples/WEB-INF/classes/insync.</li>
<li>Add the following destination to blazeds/tomcat/webapps/samples/WEB-INF/flex/remoting-config.xml:</li>
<p><pre class="brush: xml;">
&lt;destination id=&quot;contacts&quot;&gt;
        &lt;properties&gt;
            &lt;source&gt;insync.dao.ContactDAO&lt;/source&gt;
            &lt;scope&gt;application&lt;/scope&gt;
        &lt;/properties&gt;
&lt;/destination&gt;
</pre>
</p>
<li>Copy insync/sampledb/insync to blazeds/sampledb/insync</li>
<li>Edit server.properties in blazeds/sampledb, and modify the file as follows to add the insync database to the startup procedure.
<p><pre class="brush: jscript;">
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
</pre>
</p>
</li>
<li>Start the database (startdb.bat or startdb.sh)</li>
<li>Start BlazeDS</li>
<li>Run the application</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2009/07/building-a-flex-application-with-the-parsley-framework/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>The &#8220;Spring ActionScript&#8221; Framework – Part 2: Autowiring</title>
		<link>http://coenraets.org/blog/2009/03/the-spring-actionscript-framework-%e2%80%93-part-2-autowiring/</link>
		<comments>http://coenraets.org/blog/2009/03/the-spring-actionscript-framework-%e2%80%93-part-2-autowiring/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 13:15:16 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=111</guid>
		<description><![CDATA[In the first part of this series, we looked at how the “Spring ActionScript” framework can help you externalize the configuration and the wiring of your components, and how you can easily obtain configured objects using applicationContext.getObject(). In this second part, we will discuss how you can make these objects available to the views of [...]]]></description>
			<content:encoded><![CDATA[<p>In the first part of this series, we looked at how the “Spring ActionScript” framework can help you externalize the configuration and the wiring of your components, and how you can easily obtain configured objects using applicationContext.getObject().</p>
<p>In this second part, we will discuss how you can make these objects available to the views of your application without tightly coupling these views to the framework, and without passing references around through potentially many levels of view containment.</p>
<p>We will build the &#8220;Spring ActionScript&#8221; version of the InSync contact management application I often use in this blog to explore new technologies. The application has two views: MainView and ContactForm. Both need a reference to a contact RemoteObject to work.</p>
<p>NOTE: This example is intentionally kept simple. In a more partitioned application, you may want to pass a more abstract controller around as opposed to a specific RemoteObject. We will use this approach in part 3.</p>
<p>The views could use applicationContext.getObject() to access their dependencies (in this case the contact RemoteObject), but this approach has a number of problems:</p>
<ol>
<li>With a dependency on applicationContext, the views would be tightly coupled to the framework.</li>
<li>We would still need to pass a reference to the applicationContext object to the views. This is often solved using the singleton approach which has its own set of problems.</li>
</ol>
<p>So, instead of the views instantiating or looking up their dependencies, a better approach would be to &#8220;inject&#8221; these dependencies into the views.</p>
<p>Unlike Swiz, &#8220;Spring ActionScript&#8221; doesn’t currently have built-in support for an [Autowire] annotation, but Christophe Herreman <a href="http://forum.springsource.org/showthread.php?t=67319">seems to imply</a> that this feature is coming, and in the meantime, he provides <a href="http://www.herrodius.com/blog/158">some sample code</a> to support  &#8220;Spring ActionScript&#8221;-powered autowiring in your application. Using this custom code, the inSync application looks like this:</p>
<p><span id="more-111"></span></p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
	applicationComplete=&quot;applicationCompleteHandler()&quot;&gt;

	&lt;mx:Script&gt;
	&lt;![CDATA[

	import insync.views.MainView;
	import mx.utils.DescribeTypeCacheRecord;
	import mx.utils.DescribeTypeCache;
	import as3reflect.ClassUtils;
	import org.springextensions.actionscript.context.support.FlexXMLApplicationContext;

	private var applicationContext:FlexXMLApplicationContext;

	private function applicationCompleteHandler():void
	{
		applicationContext = new FlexXMLApplicationContext(&quot;applicationContext.xml&quot;);
		applicationContext.addEventListener(Event.COMPLETE, applicationContextComplete);
		applicationContext.load();
	}

	private function applicationContextComplete(event:Event):void
	{
		systemManager.addEventListener(Event.ADDED, addedEventHandler);
		var mainView:MainView = new MainView();
		addChild(mainView);
	}

	private function addedEventHandler(event:Event):void
	{
		var autowiredObject:Object = event.target;
		trace(&quot;Added to display list: &quot; + autowiredObject);
		var typeInfo:DescribeTypeCacheRecord = DescribeTypeCache.describeType(autowiredObject);
		for each (var metaDataNode:XML in typeInfo.typeDescription..metadata)
		{
			if (metaDataNode.attribute(&quot;name&quot;) == &quot;Autowired&quot;)
			{
				var propertyNode:XML = metaDataNode.parent();
				var property:String = propertyNode.@name.toString();
				trace(&quot;Found Autowired property: &quot; + property);
				var objectName:String = property;
				var autowireByType:Boolean = true;

				for each (var arg:XML in metaDataNode.arg)
				{
					if (arg.attribute(&quot;value&quot;) == &quot;byName&quot;)
					{
						autowireByType = false;
					}
				}

				if (autowireByType)
				{
					var clazz:Class = ClassUtils.forName(propertyNode.@type.toString());
					var objectNames:Array = applicationContext.getObjectNamesForType(clazz);
					if (objectNames.length == 1)
					{
						objectName = objectNames[0];
					}
				}
				trace(&quot;Autowiring: &quot; + property + &quot; in &quot; + autowiredObject);
				autowiredObject[property] = applicationContext.getObject(objectName);
			}
		}
	}

	]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:Style source=&quot;styles.css&quot;/&gt;

&lt;/mx:Application&gt;
</pre>
<p>To be able to inject properties annotated with Autowired, we register as a listener for the ADDED event on systemManager, and introspect each object added to the display list. If the object has [Autowired] properties, those properties are injected (by name or by type) using applicationContext.getObject(objectName).  This is also the approach taken by Swiz.</p>
<h3>Timing</h3>
<p>Before you inject objects into views, you need to make sure the applicationContext.xml file has been loaded and that the objects it defines have been instantiated. To that effect, the applicationContext dispatches an Event.COMPLETE event when it is ready. To make sure all the views of my application can be properly injected (if needed), the strategy I use in this application is to start instantiating the main view only after this event has been triggered. See addChild(mainView) in the applicationContextComplete handler.</p>
<h3>The Views</h3>
<p>With that infrastructure in place, the two views of the InSync application are easy to write. Their basic setup looks like this:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Canvas xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;&gt;

	&lt;mx:Script&gt;
		&lt;![CDATA[

			import mx.rpc.remoting.mxml.RemoteObject;

			[Autowired]
			public var contactRemoteObject:RemoteObject;

		]]&gt;
	&lt;/mx:Script&gt;

&lt;/mx:Canvas&gt;
</pre>
<h3>Installation instructions</h3>
<p>NOTE: If you already installed <a href="http://coenraets.org/blog/2009/02/sample-application-using-the-swiz-framework-and-blazeds/">the Swiz version of inSync</a>, you can skip steps 1, 3, 4, 5 and 6.</p>
<ol>
<li>Install the <a href="http://opensource.adobe.com/blazeds">BlazeDS turnkey server</a>. (To be clear: you don’t have to use BlazeDS to use Spring ActionScript… That’s just what this sample is using.)</li>
<li>Download <a href="http://coenraets.org/downloads/insyncspringas/insyncspringas.zip">insyncspringas.zip</a>, and unzip it on your local file system.</li>
<li>Copy insyncspringas/java/classes/insync to blazeds/tomcat/webapps/samples/WEB-INF/classes/insync.</li>
<li>Add the following destination to blazeds/tomcat/webapps/samples/WEB-INF/flex/remoting-config.xml:</li>
<p><pre class="brush: xml;">
&lt;destination id=&quot;contacts&quot;&gt;
        &lt;properties&gt;
            &lt;source&gt;insync.dao.ContactDAO&lt;/source&gt;
            &lt;scope&gt;application&lt;/scope&gt;
        &lt;/properties&gt;
&lt;/destination&gt;
</pre>
</p>
<li>Copy insyncspringas/sampledb/insync to blazeds/sampledb/insync</li>
<li>Edit server.properties in blazeds/sampledb, and modify the file as follows to add the insync database to the startup procedure.
<p><pre class="brush: plain;">
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
</pre>
</p>
</li>
<li>Start the database (startdb.bat or startdb.sh)</li>
<li>Start BlazeDS</li>
<li>In Flex Builder, create a new Flex project called insyncspringas. You don’t have to select any &#8220;Application server type&#8221;. </li>
<li>Copy spring-actionscript.swc and as3reflect.swc from insyncspringas/flex/lib to the lib directory of your project</li>
<li>Copy the files and folders from insyncspringas/flex/src to the src directory of your project</li>
<li>Open applicationContext.xml and make sure the remoteObject endpoint value matches your server setup.</li>
<li>Run the application</li>
</ol>
<h3>Note on Autowiring and Performance</h3>
<p>Annotation-based dependency injection is elegant and easy to work with. However, the current implementation that requires a describeType on every object added to the display list has a performance impact. This is maybe something that the Flex framework could help with in the future. For example, we could inject code at compile time to dispatch an AutowireEvent for each Autowired property when a class is instantiated. We would leave it up to the frameworks to provide a specific injection implementation. That would give these frameworks a better event to listen to, and they wouldn’t have to introspect all the objects added to the display list. An alternative would be to have a compiler hook to allow annotation-based code injection at compile time.</p>
<p>In the meantime, you’ll have to identify if the performance impact of the current approach is acceptable in the context of your application. If not, there are ways to improve the basic approach described above:</p>
<ul>
<li>Using Swiz, <a href="http://aralbalkan.com/1960">Aral Balkan uses an autowire property</a> on the views that require autowiring. In the autowiring code, he then uses the hasOwnPropety(&#8220;autowiring&#8221;) function to identify if the object needs to be autowired before using describeType. This approach still requires some level of introspection on each object added to the display list.</li>
<li>Swiz now makes sure it doesn’t perform describeType on classes in the mx packages. This approach could also be added to the code above.</li>
<li>Another approach would be for you to programmatically dispatch an AutowireEvent in the initialize event of the views that need to be autowired. This approach is maybe less elegant than a simple annotation, but wouldn’t have the performance impact of introspecting all the objects added to the display list. It would also work for any object in your application, not only the views.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2009/03/the-spring-actionscript-framework-%e2%80%93-part-2-autowiring/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>
