What's new? | Help | Directory | Sign in
Google
                
Search
for
Updated Sep 21, 2008 by Chris.Scott.One
DefiningApplicationComponents  

Defining Application Components

With your project set up, it's time to tell Swiz about your application components. Swiz's primary goal is to assist you in building Flex applications in a true MVC paradigm. Your application will need RemoteObjects, utilities, data collections, commands, events, etc, to function. Your views, in turn, will need to access all of these. Swiz provides a very simple way to encapsulate components into Controllers, which are automatically provided to the Views that need them.

We'll start by defining some components for our application, defined in a custom BeanLoader. BeanLoader is a special Swiz utility for loading components into it's central factory. Create a new mxml component somewhere in your source directory and name it 'Beans.mxml'. By default this will be based on Canvas, we'll switch it to Swiz's BeanLoader class. Change the contents of your new Beans.mxml file to look like the following:

<?xml version="1.0" encoding="utf-8"?>
<BeanLoader xmlns="org.swizframework.util.*" xmlns:mx="http://www.adobe.com/2006/mxml">

</BeanLoader>

We'll add a RemoteObjects and also a DynamicChannelSet, which enables us to remove the dependency on services-config.xml:

<BeanLoader xmlns="org.swizframework.util.*" xmlns:mx="http://www.adobe.com/2006/mxml">
	<!-- custom channel set -->
	<DynamicChannelSet id="myAmfChannel">
		<serverPort>8080</serverPort>
		<contextRoot>/demo-web</contextRoot>
	</DynamicChannelSet>
		   
	<!-- user service --> 
	<mx:RemoteObject id="userService" 
				  destination="userService" 
				  channelSet="{myAmfChannel}"/>
</BeanLoader>

When our application loads, we want to tell Swiz to process this BeanLoader, in order to create instances of these components. Swiz will store them in an internal factory. We can accomplish by adding a function in our application's main view, in an mx:Script block. We''ll create an onPreinitialize function, which I will attach to the main application's preinitialize event.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
			layout="absolute" width="100%" height="100%"
			preinitialize="onInitialize()">

	<mx:Script>
    	<![CDATA[
		import org.swizframework.Swiz;

		private function onInitialize() : void {
			// load up swiz beans
			Swiz.loadBeans( [ Beans ] );
		}
	]]>
     </mx:Script>

	<!-- rest of view -->

</mx:Application>

Because Swiz ties itself into your applications creation life cycle, in order to autowire your views, you want Swiz to initialize as early as possible, the preinitialize event is before any views are added to the stage. You then pass in a list of classes to loadBeans that are the various BeanLoaders you may have created. Notice the way that the class is passed in, similarly to the way PopupManager works. You are not passing in an instance, Swiz will handle loading everything for you. You are free to create as many BeanLoaders as you like for organization. I tend to create separate loaders for my RemoteObjects, Swiz will find all your components when it comes to autowire everything.

Let's add some more interesting things to our BeanLoader.

<BeanLoader xmlns="org.swizframework.util.*" xmlns:mx="http://www.adobe.com/2006/mxml">
	<!-- custom channel set -->
	<DynamicChannelSet id="myAmfChannel">
		<serverPort>8080</serverPort>
		<contextRoot>/demo-web</contextRoot>
	</DynamicChannelSet>
		   
	<!-- user service --> 
	<mx:RemoteObject id="userService" 
				  destination="userService" 
				  channelSet="{myAmfChannel}"/>
	
	<!-- user controller -->
	<controller:UserController id="userController"/> 
</BeanLoader>

Our UserController is going to use the RemoteObject to make remote calls to our backend services. In order to tell Swiz about this relationship, we need to add a property to the UserController for the RemoteObject, which we have given the id "userService" in our BeanLoader.

public class UserController extends AbstractController
{
		
	[Autowire(bean="userService")]
	public var userService : RemoteObject;

	public function UserController() { }

	// rest of class...
}

You'll notice that we have defined a local variable of type RemoteObject, which we have annotated with Swiz's Autowire metadata. The Autowire is used to define the bean name, which is the id we used in the BeanLoader, where the dependent object can be found. When Swiz processes your BeanLoaders, it caches all the objects they contain in a central factory and interrogates them to find their Autowire metadata elements. If Swiz can find a bean in its local cache matching the bean name you provided, it will inject it into the variable where the Autowire metadata is defined. Because the userController above requires the userService to function, we call it a dependency. When Swiz loads all your beans, it injects their dependencies for you. We call this Dependency Injection, it's the primary purpose if Swiz's internal factory. When you later ask Swiz for one of your components, you can be assured that as long as you defined each of its dependencies somewhere in a BeanLoader, the component will be returned to you all wired up and ready to use. Although this may seem like a round about way to create your application components, there are tremendous benefits to the approach. By externalizing dependency management, your components are only concerned with their primary business logic. If you get into the habit of using interfaces, and only program to the interfaces of your components' dependencies, you gain the ability to swap out implementation with very little effort, by simply altering your bean definitions in your BeanLoaders. Although a full discussion of Inversion of Control is outside the scope of this getting started document, if you are new to IoC, I would strongly suggest looking over some of the links provided in the Resources section.

Now that we have defined some components lets move on to making Async requests through your RemoteObject and how Swiz can make this simpler.

Next: SwizControllers


Comment by paulo.quintans, Aug 18, 2008

This is a wonderful job. I like very much the idea of this framework. Still, browsing through the code, I wasn't clear how this framework would behave, when working with modules. Do the beans get injected, when loading and unloading modules?

Comment by tylerChesley, Aug 27, 2008

I'm interested in how Swiz would work with modules as well.


Sign in to add a comment