A few weeks back I wrote an article saying that I was just starting to work with AS3 Signals and the Robotlegs framework at my new job. Since then I have written a post about AS3 Signals and now it is time to write about Robotlegs. Since there is so much to write about with regards to Robotlegs I had to break out one chunk to discuss.
In working with the framework, reading lots of documentation and finding it central in the diagram above, I thought it best to start with the Context class in the Robotlegs framework.
Robotlegs is an MVCS framework similar to Pure MVC that relies on metadata based dependency injection. On the surface the first cool thing is that you can use the Inject metatag to populate class fields automagically. More automagic part of the framework is that mediators automatically get created when the view they are mediating gets added to the stage. Finally it has a very elegant central event dispatcher and Command pattern model that you barely need to do anything to get working. All this is possible because of the Context.
Getting [Inject] to work
// It really is just this easy [Inject] public var obj:MyClass;
Most of the power of Robotlegs comes from the use of the Inject metatags letting the framework. However, the framework can't inject anything until it knows what to inject. This is almost entirely done in the Context and I am going to go through the main functions here. Keep in mind that all these methods also have their inverses to undo these acts but I'll let you look those up on your own. For now I'll keep it simple and we can get to more advanced usages in other articles.
injector.mapValue is used when you already have a class instantiated and you want to use that object as a singleton in this application context. The basic format is: injector.mapValue(whenAskedFor:Class, useValue:Object) and might look like this:
var myObject:MyClass = new MyClass(); injector.mapValue( MyClass, myObject );
If you want to do something similar without first instantiating the object, you can use mapSingleton. The format for that is: injector.mapSingleton( whenAskedFor:Class ) and the above example would be changed to this.
injector.mapSingleton( MyClass );
injector.mapClass is used when you want the injector to create a new instance of a class every time it is asked to inject that class somewhere. The format for this function is injector.mapClass( whenAskedFor:Class, instantiateClass:Class ) and if we decided against using a singleton for MyClass instances the above examples would become:
injector.mapClass( MyClass, MyClass );
That last one may seem wierd because you type MyClass twice. However, this is because you could pass in any class that extends MyClass for the instantiateClass parameter ( or implements it if it were an interface ).
Once you've used one of these 3 commands ( or some of the others I can talk about at another time ) on all the values you want to inject in your application, anytime the framework creates or manages a class object it will have the information it needs to do just that. So how do you go about getting Robotlegs to create a class object? Automagic mediators are a perfect example.
In Pure MVC like architectures the Mediator classes handle communication between their views and the rest of the application. Since Robotlegs is an MVCS framework based on Pure MVC this is a perfect opportunity to have the framework create the mediator for you. From the Context class you only have to write something similar to:
mediatorMap.mapView( MyView, MyViewMediator );
In this MyView is a view class and MyViewMediator is the mediator designed for it. Now the application will automagically create a MyViewMediator object when any MyView object is added to the stage and inject a reference to the MyView object into it. It will also destroy the MyViewMediator object just as magically when the MyView object gets removed from the stage. I can write much more about this in an article on the Mediator/View relationship that I plan to write in the near future.
Events, Commands and tying it all together
Robotlegs uses a centralized event dispatcher throughout to keep the model, view, controller and service sections decoupled from each other and yet tying them together at the same time. One major part of the centralized dispatcher is triggering Commands. If you've read this far, I thank you and I'm guessing you already know about the Command pattern.
To set up the command pattern in the your Robotlegs Context class just use the following format. commandMap.mapEvent( eventType:String, commandClass:Class ) which might look like this:
commandMap.mapEvent( MyCustomEvent.SOMETHING_IMPORTANT, DoSomethingImportantCommand );
Now, whenever a class in the framework dispatches the SOMETHING_IMPORTANT custom event the DoSomethingImportantCommand will be created and executed. As a bonus, the specific instance of MyCustomEvent can be injected into the command with a single line:
[Inject] public var event:MyCustomEvent;
So this article did not have had any sexy embedded SWF files that use Robotlegs. However, this framework's strength is not about sexy SWF files but its ease of use which should make creating that sexy file go quicker. The context file is the heart of Robotlegs and using the few methods I've written about here you can use it to make a fairly robust application linked together with dependency injection.
I've purposely left a lot out of this post. This is because I just want to wet your appetite to give it a shot as well. Also, I'd like to hear what kind of questions come up for you in the comments. Finally, I could write a lot more just about the context class and favoring configuration over convention( well sort of ), but it would just turn into a mess of words and I'd be surprised if you read this far anyway. If you did, thank you. I'd love to hear what you think of Robotlegs if you've tried it out or even if you've decided not to.