Another is you have some flexibility with injection rules. There are too many to cite, but here's a couple.
Most Models are singletons for whatever reason. Say you only ever have 1 User logged into your application, thus, you make the User Model a Singleton as well. However, you don't have to make it a Singleton. You can simple map it as such:
injector.mapSingleton(UserModel)
That way, you can still instantiate the class with multiple instances if you want to test something, or use it elsewhere. Additionally, if you change your mind later, you can just update the injector to map it as an instance instead. It's subtle, and an edge use case to me, but certainly a nice to have in the beginning of projects where you are figuring out your data model, or you're waiting on the server guys to tell you what the bloody hell it actually is.
Another one is injecting interfaces. Now, I'm only a fan of Interfaces in API's. It makes sure that developers aren't locked into your class structure, and your API is flexible enough for their needs, yet ensures you can actually support it without breaking future changes since the interface ensures (for the most part *ahem*) implemented behavior doesn't' change.
Eventually, though, SOMEONE has to instantiate this interface as a concrete implementation. This someone will be using a class to do so. That code, often, is concrete as well; meaning, not configurable. Using injections, however, it is. That, and rules to do so are separate from the implementation. The most common use case for this is when you're working on a project that has a brand new middle tier. Perhaps, since you're a Flash dev, you're WAYYYY faster than the back-end dudes. So, you're reading to start using a UserVO in your application... but the server guys don't even have a dev server for you yet.
No problem, you use a MockLoginService instead. It'll login, and give you a UserVO:
[Inject]
public var loginService:ILoginService;
However, the next day, the devs give you a real service. Cool, you code a real LoginService to parse the response, and ensure it's a valid response + valid user. If so, great.
[Inject]
public var loginService:ILoginService;
Noticed nothing changed. The only thing that changes in the rules in your Context (or whatever you're using to setup your service rules; see Joel's startup manager).
This:
injector.mapClass(ILoginService, MockLoginService);
Would go to this:
injector.mapClass(ILoginService, LoginService);
No matter how many classes utilize ILoginService, nothing for them changes. They have no clue whether they are talking to a local XML file, or a real dev server... or a staging server, etc. This also has benefits for Mock data in unit tests, and others.
Regardless, it's nice to have an easier way to participate in the whole "coding by contract" that Interfaces provide. Now you can more easily configure what those interfaces actually become.
In conclusion:
- more flexibility with Singletons, specifically for data
- more flexibility when coding by contract via interfaces