9 Feb 2009

Swiz: Inversion of Control/Dependency Injection framework for Flex and ActionScript

A few days ago I stumbled upon Swiz, which bills itself as the "brutally simple micro-architecture for Rich Internet Application development with Adobe Flex." If the term micro-architecture or the buzzword Rich Internet Application haven't scared you off yet, read on, because it really is a lovely little framework.

Swiz is a lightweight framework for Flex (and ActionScript) that lets you separate your business and presentation logic and implement a loosely-coupled event-based architecture in your applications. I've purposefully stayed away from using the terms Inversion of Control (IoC) and Dependency Injection (DI), even though Swiz is, at its core, an IoC framework that lets you carry out DI. The reason? I feel people get too caught up on the fancy names and either get scared off or end up blindly implementing patterns and frameworks without really understanding what they're doing or why they're doing it. Thankfully, Swiz is simple enough that you can actually understand what it does and why it does what it does. And, it doesn't pigeonhole you into a color-by-numbers straitjacket or suffocate you under a mountain of boilerplate code like some other frameworks.

This blog post is not meant to be an introduction to Swiz. For that, read the Getting Started guide, watch the introductory video by Swiz creator Chris Scott from his presentation at 360Flex last year, and read the Swiz posts on Sönke's blog and those on Chris's blog.

Instead of an introduction, I want to document how I'm using Swiz and the modifications I've made to it in hopes that they might help other developers and possibly spark conversation on future features.

Open a window, let some AIR in

(Sorry, I couldn't resist!)

I ran into a couple of issues with Swiz when I finally got the chance to play with it yesterday. First off, I couldn't get the autowiring to work with new Window instances in AIR. Googling around, I found that this was a known issue and that Sönke had already applied a fix in the form of a registerWindow() method that you call before opening your window. The fix, however, didn't work for me without an additional little patch to manually force the autowiring on the Window class itself. So my registerWindow() method ended up looking like this:

public function registerWindow(window:IEventDispatcher):void
{
    window.addEventListener(Event.ADDED_TO_STAGE, handleAutowireEvent, true);
    window.addEventListener(Event.REMOVED_FROM_STAGE, handleAutowireEvent, true);
    autowire(window);
}

With that little change, my new Window instances get autowired correctly.

Wrrooom, wrrrrooom!

I also saw that the autowiring code was causing quite a bit of performance slow-down. So I decided that autowiring should be opt-in. I modified the framework so that only classes that have a public autowire property declared are autowired. I usually declare this in my classes like this:

public var autowire:Boolean = true;

I could have made it so that I used a metadata tag instead but the whole idea was to stay away from the overhead of describeType. (I'm not sure what additional overhead describeType's XML conversion adds on to the internal describeTypeJSON method but I have a feeling it's quite substantial. If so, it would probably be nice to have a method to just return metadata for a given class — in the spirit of getQualifiedClassName — to make it more performant to parse metadata at runtime.)

So my handleAutowireEvent() method in the Swiz class looks like this now:

private function handleAutowireEvent(e:Event):void {
	// Autowiring is strictly opt-in for performance/efficiency, and
	// having an explicit flag in the class should make your intent clearer.
	if (e.target.hasOwnProperty("autowire")) {
		autowire(e.target);
	}
}

Similarly, the handleRemoveEvent() method simplifies to:

private function handleRemoveEvent(e:Event):void {
	if (e.target.hasOwnProperty("autowire")) {
		_beanFactory.unwire(e.target);
	}
}

The performance increase has been striking: the overhead of Swiz, with this change, is entirely negligible whereas before I was experiencing a doubling in the initialization time of my app.

In case you make the same changes, you should also update registerWindow() (hey, every cycle counts right? Or something like that!):

public function registerWindow(window:Window):void
{
    window.addEventListener(Event.ADDED_TO_STAGE, handleAutowireEvent, true);
    window.addEventListener(Event.REMOVED_FROM_STAGE, handleRemoveEvent, true);
 
	// Fire the autowire manually for the window itself.
	if (window.hasOwnProperty("autowire")) {
		autowire(window);
	}
}

Flex Framework? How about ActionScript and Flex Framework?

I'm also using Swiz quite differently to how it was originally intended. Originally, you're supposed to declare your beans (beans? What are we Java?) in MXML. I found this unnecessarily limiting. So I declare my beans (or components; since neither ActionScript nor Flash are a type of coffee) in ActionScript. And, although I'm using Swiz on a Flex app currently, I don't see any reason off the top of my head why you couldn't use it in ActionScript-only projects too.

Here's a sample Beans class in ActionScript showing you how it's done:

package com.mydomain.myawesomeapp
{
	import org.swizframework.util.BeanLoader;
 
	import com.mydomain.myawesomeapp.SomeController;
	import com.mydomain.myawesomeapp.SomeService;
 
	public class Beans extends BeanLoader
	{
	        // Simply instantiate and return an instance...
		public function get someController():SomeController {
			return new SomeController();
		}
		public function set messageController(o:*):void {};
 
              // ... or do some configuration beforehand
		public function get someService():SomeService {
			var someService:SomeService = new SomeService();
			someService.configureSomething("like", "totally", "cool");
			return someService;
		}
		public function set twitter(o:*):void {};
 
		public function Beans() {
			super();
		}
	}
}

So, basically, what we're doing is mimicking the methods in the ActionScript class that would have been generated from the MXML (or, more precisely, giving Swiz exactly what it's looking for in the BeanLoader, which are readwrite accessors; this is why we need the setter even though it doesn't do anything.)

And, finally, a gotcha that I find myself falling into: Remember to make anything you're going to [Autowire] or [Mediate] public. This means the properties that will receive the class instances and the event handlers. Since you'll be used to automatically making these private, take extra care!

In closing

Swiz is a lovely, lightweight framework that I'm really enjoying working with. It also has a small but active community and some good developers behind it. Play around with it, why don't 'cha and let me know what you think of it in the comments!

Add Your Comment

Spam Protection by WP-SpamFree

A lovely little framework called Swiz

  1. I’d be interested in how Swiz compares to the Mate framework (ease of use, etc.)

    bjorn
  2. Very nice write-up, Aral. Did you try Mate?
    I’ve been looking for time to compare Swiz and Mate, but haven’t found the time to try either. So I’m still stuck under the weight of Cairngorm :)

    Christian H. Mosveen
  3. Hi,
    it’s interesting that frameworks seem all the rage these days. I already have to deal with one framework, it’s called Flex, and I don’t particularly feel like adding another layer. So please, no framework!
    Ariel

    ariel sommeria
  4. Hi Ariel,

    You’re absolutely correct, Flex is a framework itself. It’s based on MVC and the event model and you absolutely do not need a framework on top of it to build your applications. If you want to use MVC for your own app, you can simply do so using nothing but events and data binding. A simple MVC example in Flex alone takes under ten lines of code.

    I debated whether I should get into my usual tirade on heavy-weight frameworks and decided not to in this post. My own framework, Arp, which I’m no longer developing, was about as lightweight as I could get it and yet, it still had boilerplate code and I fell out of love with it a while ago.

    In that sense, Swiz is not a framework in the traditional sense. Think of it as giving you the ability to loosely couple parts of your application and for elegantly handling application-level events (what I used to call “system events” in Arp), etc.

    Aral
  5. [...] seems that every other flex-related post I read these days is about this or that framework and how well it does Inversion Of Control and [...]

    arielsommeria.com/blog/ » Blog Archive » Framework Overload
  6. Hi Aral,
    I think we have similar lines of thinking on heavy-weight frameworks. I just elaborated on my comment in a post over here http://arielsommeria.com/blog/?p=61, so thanks for the inspiration! And I’ll try to take a look at Swiz, even if I’m biased ;-)

    ariel sommeria
  7. Regarding Mate, etc., check out Tony Hillerson’s recent comparison, or jump directly to his conclusions.

    Aral
  8. Hi Aral, cool article!
    I’ll look into the registerWindow thing you reported and I have set the issue back.
    About the performance optimization with hasOwnProperty(”autowire”) we might think about different approaches. Currently we ignore classes from the mx.* and flash.* (see Swiz.handleAutowireEvent) package which already was a great performance improvement since getQualifiedClassName is way faster than describeType.
    It might be an approach to define an explicit package which is used to determine if autowire should apply or not.
    Something like Swiz.setAutowirePackage(”com.foo.myproject”)
    With this you could avoid to define the autowire variable in every class which imo adds to much framework dependency.

    Sönke Rohde
  9. Hey Sönke,

    Thanks! Let me know if you have trouble replicating the issue on your end.

    Re: autowire opt-in, your package-based solution sounds fine though I’m going to stick to explicitly marking each class as that’s still more efficient. Since the properties are just simply properties, I’m not too worried about framework dependency (i.e., the class will run just fine without the framework; it’s just metadata by another name) and it does mean that _only_ the classes I mark get autowired and not one more (control freak? What do you mean control freak?) :)

    Aral
  10. [...] > Aral Balkan – A lovely little framework called Swiz [...]

    localToGlobal » Blog Archive » news review -> 7th week of 2009
  11. [...] stumbled upon a framework called Swiz, delved deeper without getting scared when it called itself the “brutally simple [...]

    Rounding up Last Week One Day Later
  12. Nice writeup Aral! Sönke has added the registerWindow tweaks, and we have actually been talking about various ways to reduce the scope of autowiring for a while now. I think that there are going to be some significant enhances very soon in terms of far speedier reflection for AS, which we will be taking advantage of.

    Ariel, I actually fully agree with you, and have made the same point in sessions I have given on Swiz. There is very little we have done to replace or compete with the Flex framework, only add tools to make things simpler. What Swiz has done for my own development is reduce code considerably and provide looser coupling.

    Chris Scott
  13. Btw. Your copyright at the bottom says “2008″ :)

    Jonas
  14. a small working example will be greatly appreciated.

    Sudhansu
  15. [...] Swiz, Aral Balkan uses an autowire property on the views that require autowiring. In the autowiring code, he then uses the [...]

    Christophe Coenraets » Blog Archive » The “Spring ActionScript” Framework – Part 2: Autowiring
  16. [...] Or this, if you want to see how to do a similar thing with Swiz: link [...]

    AS3 Dependency Injection and [Autowire] « shaun smith
  17. [...] 1.使用Swiz, Aral Balkan在需要使用自动分配对象的视图中使用autowired属性,代码中,使用describType方法之前先用hasOwnproperty(”autowiring”)方法来来判断对象是否需要自动分配。但该方法在某种程度上还是需要对每个显示对象进行内省分析。 [...]

    翻译(THE “SPRING ACTIONSCRIPT” FRAMEWORK) « Raven’s Blog
  18. What is this describeTypeJSON you speak of? I’ve never heard of it, nor have any colleagues or my friend Google.

    Ben Clinkinbeard
  19. Swiz is the best! I like it better than Mate, personally.

    Ansury