ModelLocator Dependencies in Cairngorm

I'm new to Flex, but realizing the benefits of using a framework in a team environment I decided to give Cairngorm a try for my first real Flex project. I had heard some not-so-good things about Cairngorm from a lot of developers I know and respect, but I figured I had to see for myself. At first I didn't really see much wrong with the micro-architecture. Sure there was a lot of repetitive boilerplate, but I was using a code generator so it wasn't that bad. Things were going along pretty well, that is until I got about half-way through the project and began to work on the administrative interface for this application, which happened to be a separate Flex application. Well, it turns out the administrative application could have reused a lot of the main application's views, that is if they didn't have hard coded references to the ModelLocator all over the place. Most of the script blocks in my views started out with statements like:


private var modelLocator:ModelLocator = ModelLocator.getInstance();

and I now needed:


private var modelLocator:ModelLocator = ModelLocator.getInstance();

Now to be fair this is probably a newbie mistake. I could have gotten around this specific issue by breaking up my model or organizing my project differently, but it highlights a key issue with the ModelLocator: it is tightly coupled to views. My views had hard coded references to classes that I needed to change depending on where the view was to be used, and that was a problem. This is actually a very common issue with a well known solution called dependency injection. Rather than the views being responsible for getting their dependencies, and thus having to know were to get them, the views have their dependencies supplied to them by some outside dependency manager. (I'm certainly not the first to run into this issue. Theo Hultberg has an excellent post on the many issues with Cairngorm's ModelLocator that I suggest any Cairngorm user read.)

Enter Mate and Swiz

There are some frameworks that provide dependency injection for Cairngorm and Flex in general, but two relatively new Flex frameworks, Mate and Swiz, handle the problem of dependency management in their own way, as part of the core framework. Mate uses MXML to define dependencies in what that framework calls an EventMap while Swiz uses metadata annotations to wire objects together. While I haven't built anything with either framework yet, both seem to be huge improvements over the hard coded import statements I found myself using in Cairngorm. Unfortunately for me both Mate and Swiz were introduced just weeks after I began this project, but I'll definitely be using one of these frameworks on my next Flex project.

Raul Riera's Gravatar What code generation are you using for Craigorn?
# Posted By Raul Riera | 7/11/08 5:32 PM
Nathan Mische's Gravatar I'm using a hacked up version of Cairngen -
# Posted By Nathan Mische | 7/12/08 11:59 AM
Douglas Knudsen's Gravatar "but it highlights a key issue with the ModelLocator: it is tightly coupled to views."

Only if you the developer chooses to couple them, yes. In your case, your component should have exposed a public property representing the data it needs and its parent inject this data. Of course this parent might benefit from some DI love.

# Posted By Douglas Knudsen | 7/14/08 5:34 PM
Nathan Mische's Gravatar "...your component should have exposed a public property representing the data it needs and its parent inject this data." This is dependency injection, however the <a href=" articles</a> on Cairngorm state:

"Additional strategies include passing data up and down through MXML component instantiations. Consider the following representation of MXML components, where data is in a leaf node of the tree and is required in another developer's leaf node. The only solution is to find a common branching point for both leaf nodes and then, from that branching point, pass the data down through the component chain with component instantiations, as follows:

<myView:MyComponent data="{}" />

Once again, this is a strategy that is very brittle, and changes in the implementation of the view are quite difficult. It leads to regular errors when developers incorrectly pass data down the chain somewhere, or when they change views, causing the data to not reach its intended destination. Debugging these errors is a laborious job of tracing the component paths to confirm that data has been correctly passed between components. It's a frustrating task and not recommended."

This is what I remember reading and all of the examples I saw created a direct reference to the ModelLocator as I have in the sample code above.

Having said that, it seems the introductory documents have been updated since I last read them because they now go on to say:

"This brings up an important best practice. When you create components that rely upon client-side data, it is all too easy to create a direct reference to a Singleton model, such as ShopModelLocator. Indeed this is true throughout the application. We discourage this approach. Instead, consider passing the model and/or its properties down through a hierarchy of your view components, for a cleaner and more thoughtful solution." (The article was last updated May 23, 2008, but I have no idea when this second recommendation was added. I'm pretty sure it wasn't there when I read these articles in late April.)

So it seems the introductory articles don't give a consistent recommendation on how to use the ModelLocator. While you can do DI by passing data up and down the MXML component chain, I agree with the first recommendation and see this as being a major pain to manage.
# Posted By Nathan Mische | 7/14/08 9:25 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.