MXML and Dependency Injection

I am a huge fan of the Spring framework for Java because it helps me to build applications that are very loosely coupled. When I look at MXML it seems to me that it could be used in a similar fashion to Spring’s application context. In this article I’m going to explore that possibility and talk a little about why loose coupling is good.

The basic idea [with Dependency Injection] is that if an object depends upon having an instance of some other object then the needed object is “injected” into the dependent object. For example, being passed a database connection as an argument to the constructor instead of creating one internally.

–Wikipedia (http://en.wikipedia.org/wiki/Dependency_injection)

I believe that most developers use this methodology when writing applications: if I need a service (an object which can do something for me), I will retrieve it, use it and forget it. This is usually done via the Service Locator Pattern or similar, or, heaven forbid, singletons.

Dependency Injection turns this on its head and instead configure objects with the services they are dependent upon from the start. This means that the code is not directly dependent on the services it needs, since it doesn’t look them up itself and the specifics of the services can be hidden behind general interfaces.

The Flex development environment supports the Dependency Injection pattern quite well, and most MXML applications are examples of it. Consider for example this code snipplet, which can be found in the Flex 2 Developer’s Guide:

<mx:List>
  <mx:dataProvider>
    <mx:Array>
      <mx:Number>94062</mx:Number>
      <mx:Number>14850</mx:Number>
      <mx:Number>53402</mx:Number>
    </mx:Array>
  </mx:dataProvider>
</mx:List>

In the snipplet an array is injected into a list in a straightforward manner, it’s not very different from how you would write it in ActionScript and you would probably not use the word “inject”, but rather say “an array is set as the data provider of a list”.

Let’s rewrite that example into something that shows the power of Dependency Injection and the abstraction it brings a little better:

<mx:Array id="numbers" 
  <mx:Number>94062</mx:Number> 
  <mx:Number>14850</mx:Number> 
  <mx:Number>53402</mx:Number> 
</mx:Array>

<mx:List width="150" dataProvider="{numbers}" />

<mx:ComboBox dataProvider="{numbers}" />

The array and list are defined separately, and we have introduced another component, a combobox.

We can inject the array into both the list and the combobox, and it’s the same array that will provide data to the components, not just the same data. If we change the array both components will change.

Let’s replace the array with another data source, for example an ArrayCollection which fetches its contents from a webservice (this code is adapted from an example on page 214 in the Flex 2 Developer’s Guide).

<mx:WebService id="numbersService">
  <mx:destination>numbersService</mx:destination>
  <mx:showBusyCursor>true</mx:showBusyCursor>
  <mx:fault>alert(event.fault.faultstring)</mx:fault>
  <mx:operation name="getNumbers"> 
    <mx:request> 
      <n>{something.selectedItem.data}</n> 
    </mx:request> 
  </mx:operation> 
  // ...
</mx:WebService>

<mx:ArrayCollection id="numbers"> <mx:source>{mx.utils.ArrayUtil.toArray(numbersService.getList.lastResult)}</mx:source> </mx:ArrayCollection>

Without any change to the components, their data is now retrieved from a remote source. The components will just accept the new data provider without change because they never knew what it was anyway. This is what is meant by loose coupling, changing one part of the application will not affect the other parts because they don’t know about the specifics, just enough to do what they are supposed to.

You can add another component which uses the same data provider without doing anything to the existing components. They don’t care that someone else uses the same provider, so they don’t have to know that, and the provider doesn’t need to know anything about the components that use it. Beautiful, isn’t it?

Conclusion

We have seen how Dependency Injection leads to more loosely coupled code and why that is a good thing. This was a trivial example but shows some of the possibilities of MXML.

You may ask if this is anything that is special with MXML and why we couldn’t just do the same in ActionScript code. Well, we could, but using MXML removes some of the tediousness that getters and setters lead to. MXML describes the objects and their dependencies a little bit more clearly that ActionScript code would.

There is one thing lacking in MXML if you compare it to Spring (there are a lot of things that are lacking, but let’s not get in to that): lazy initialization. In Spring a bean (an object, that is) is not created until it’s actually asked for. The MXML, on the other hand, seems to be compiled in such a way that the whole object graph is instantiated at once, which means that a lot of objects will be around a long time before they are needed. That is a shortcoming I am willing to live with, for the moment.

3 Responses to “MXML and Dependency Injection”

  1. The Foundry » Blog Archive » Dependency injection examples in AS3 Says:

    [...] reading Theo Hultbergs posts about dependency injection in Flash and Flex I though it appropriate to post some examples of how I [...]

  2. Christophe Herreman Says:

    Hi, in case you are interested: I’m currently working on a IoC container for ActionScript 3 called Prana. It is quite similar to Spring. There’s more info on my blog and on the sourceforge page: http://sourceforge.net/projects/prana/

  3. Peter Says:

    I’m just working on IoC container using MXML for configuration and Metadata tags for injection. Take a look if You wish.

    http://ria-workshop.blogspot.com/2008/07/actions-framework-for-flex-part-2.html

    http://ria-workshop.blogspot.com/2008/07/actions-framework-for-flex-part-3.html

Leave a Reply