Monday, March 5, 2012

Spring Actionscript 2.0 Progress Report - Part IV

Well, hello there!
Time for another progress report on the ongoing development of Spring Actionscript version 2.0. I think we're inching towards a true beta version, once I think we're feature-complete that'll happen. But not just yet. :)
So far I do encourage people to start using the library, right now within my company Stack & Heap we've been using version 2.0 in at least three of our current projects and things are running very smoothly.
Let's run through the new stuff that has been added, changed or improved.

Lazy dependency injection
This is a feature that I needed in my current project. Basically I stumbled upon a use-case where the container needed to instantiate an object that has a dependency on another object that isn't available yet at container startup.
The object in question is retrieved from the server and needs to be injected into that particular object.
Of course, its possible to just inject the instance from within the presentationmodel that performs the service call, but things get more interesting if more than one object has a dependency on the server object. And what if the server object itself needs to receive injections as well?

It would be a lot nicer to be able to just define an object definition for this server object and, once it has arrived from the server, hand it over to the container and let it handle it from there.

New Object Definition Scopes
In order to facilitate the configuration for lazy dependencies we decided to add some extra scopes to the ObjectDefinitionScope enumeration. The new scopes are:
  • ObjectDefinitionScope.STAGE
  • ObjectDefinitionScope.REMOTE
The first one, ObjectDefinitionScope.STAGE, was added to indicate that an object definition is associated with a stage component. (doh...) Before, we recommended to set the scope to ObjectDefinitionScope.PROTOTYPE for such definitions, to make sure the component didn't get instantiated as a singleton unnecessarily. But this new scope will hopefully add some clarity to the configuration.

The second one, ObjectDefinitionScope.REMOTE, is meant for the server objects I mentioned. So, the object definition is added to the configuration just as any other, with the exception that the scope is set to the aforementioned value:

 <sas:Object id="myServerObject" scope="remote" clazz="MyServerObjectClass"/>  

Now, after the object has been retrieved from the server (or any other origin than the container) it needs to be added to the container. For this you can use the manage() method on the application context:

 applicationContext.manage(serverObject);

The object definition that is associated with the instance will be looked up by type in the container. If no class can be defined in the configuration (because the class isn't available at startup for instance) its also possible to define the definition id as an optional argument:

 applicationContext.manage(serverObject, "myServerObject");

After this invocation any already existing object instances that have a dependency on myServerObject will be injected with the server object.

EventBus Configuration
As reported before, eventbus configuration can be added to the object definition in version 2.0. The original MXML config looked like this:

 <sas:Object id="dispatcher" clazz="MyDispatchingClass"/>

 <sas:EventRouter instance="dispatcher">  
  <sas:EventRouterConfiguration eventNames="{MyEventClass.SOME_TYPE}"/>  
 </sas:EventRouter>  

This has been simplified slightly, its now possible to just nest the event routing configuration directly with the object definition:

 <sas:Object id="dispatcher" clazz="MyDispatchingClass">  
  <sas:EventRouterConfiguration eventNames="{MyEventClass.SOME_TYPE}"/>  
 </sas:Object>  

Same works for event handling configuration:

  <sas:Object id="handler" clazz="{MyHandlingClass}">   
  <sas:EventHandlerMethod name="eventHandlerMethod"  
   eventName="{MyEventClass.SOME_TYPE}"/>  
  </sas:Object>  
That ought to make the overall configuration a little more concise and readable, I hope.

Context Customization
it is now possible swap out most of the internals of the object factory by adding custom implementations of the following interfaces to the configuration:
  • IDependencyInjector
  • IEventBus
  • IObjectDestroyer
  • IAutowireProcessor
Hopefully this will enable Spring Actionscript users to support more unusual use-cases that the default container logic isn't prepared for.

ApplicationPropertiesObjectFactoryPostProcessor
This processor is already present in the Spring Actionscript v1.0 and now ported to version 2.0. (Thanks @herrodius)
It enables the MXMLApplicationContext to inject a number of Application properties into its managed objects. The following properties are available:


  • application.frameRate
  • application.historyManagementEnabled
  • application.pageTitle
  • application.resetHistory
  • application.scriptRecursionLimit
  • application.scriptTimeLimit
  • application.url
  • application.url.protocol
  • application.url.host
  • application.url.port
  • application.usePreloader
  • application.viewSourceURL
And besides those, any application parameters will be added by name as well. So if the a parameter called myAppVar is passed into the application it will be available as an external property by the name of application.myAppVar.
To inject these values into an object add them into the configuration like this:

 <sas:Object id="myClass" clazz="{MyClass}">  
  <sas:Property name="frameRate" value="$(application.frameRate)"/>  
 </sas:Object>  

Default Definition Properties
Object definitions have, hopefully, sensible defaults. But we've added some shortcuts to enable you to change those without having to set these properties on every definition in the configuration.
The <sas:SASObjects/> element now has a number of the same properties as the IObjectDefinition which will be inherited by any definition within that config:
  • autoWireMode
  • childContextAccess
  • dependencyCheck
  • destroyMethod
  • factoryMethod
  • factoryObjectName
  • initMethod
  • isAutoWireCandidate
  • isLazyInit
  • parentName
  • scope
  • skipMetadata
  • skipPostProcessors
For now this is only implemented in the MXML configuration, but naturally this will also be implemented in the XML and metadata versions.

In Conclusion
Those are the newest features (I hope I haven't forgotten any actually...), apart from those, there have been quite a number of bugfixes and optimizations. The autowiring has been sped up quite a bit, as well as the dependency checker. Furthermore, my colleague @bertvandamme fixed a particularly nasty bug in the popup injection logic which would screw up the FocusManager for modal popups. Good times! :)

I haven't gotten round to updating the Spring Actionscript 2.0 documentation yet, but hopefully I'll be able to add some more to that in the near future.

New snapshots have been deployed to the maven repository as per usual.

Here are the forums if you'd like to discuss anything in public:
Spring Actionscript forum

You can follow me on twitter: @mechhead
Or follow Spring Actionscript: @springas

Our JIRA bugbase can be reached here:
SpringSource JIRA

And that's all folks, until next time, happy coding!

cheers,

Roland

No comments:

Post a Comment