I'm writing up some info on Smartypants-IOC which will hopefully make it into @dhanji's upcoming book on Dependency Injection, so I figured I'd kill two birds with one stone, and finally update my damned blog while I'm at it.
First I'll introduce a couple of key concepts:
The class+name key
Whether you're telling Smartypants what to provide, or sitting around with your hand out asking for a dependency, the key is the same. A combination of a class and a name. You need to specify the class, but the name is optional.
Injection annotations
How do you actually request a field be injected, you ask? In most circumstances you just need to annotate your fields with some ActionScript metadata. If you just want to request an instance of IServiceInterface, the syntax is simple:
[Inject] public var myService : IServiceInterface;
As I mentioned above, the injector works using a compound key of both Class and Name. Let's say you want to look up a particular String, rather than just anything. For a WSDL URL, or something along those lines:
[Inject(name="mainWSDL")] public var myServiceWSDL : String;
These fields will be injected into your object when it is constructed for you by Smartypants-IOC, or when you call injector.injectInto(myInstance).
We also have live injections, which when coupled with live rules behave like the Flex SDK's data binding functionality:
//This will be set whenever the source changes [Inject(name="userName",live)] public var currentUsername : String;
Injector Rules
Smartypants injector rules are akin to Guice's bindings. We simply use another term to avoid confusion with the Flex SDK's data-binding mechanism. You just tell the injector what you'd like it to do. Here's a couple of examples:
//Simple singleton rules:
injector.newRule().whenAskedFor(String).named("wsdl").useInstance("http://www.server.com/soap/service.wsdl");
injector.newRule().whenAskedFor(IServiceInterface).useSingletonOf(MyServiceImpl);
injector.newRule().whenAskedFor(MyConcreteClass).useSingleton();
//"Live" rules act just like <mx:Binding>
injector.newRule().whenAskedFor(String).named("userId").useBindableProperty(this, "userId");
But how do I kickstart the whole thing?
Good question! Two ways. First, in an MXML component:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:smartypants="http://net.expantra.smartypants/2008">
<smartypants:RequestInjection/>
<!-- ...Regular code and MXML... -->
</mx:Canvas>
And in ActionScript it's even simpler:
var injector : Injector = Smartypants.getOrCreateInjectorFor(this); injector.injectInto(this);
Hopefully this gives a little more insight into the style and ideas behind Smartypants-IOC. Be sure to check it out on the Google Code site, and I'd love to hear your thoughts and ideas for the future!

