here's the code:
package
{
import flash.utils.describeType;
import org.as3commons.lang.ClassUtils;
import org.puremvc.as3.patterns.facade.Facade;
import
org.springextensions.actionscript.context.IConfigurableApplicationContext;
import
org.springextensions.actionscript.puremvc.interfaces.IIocFacade;
/**
* This class provides autowiring for subclasses.
*
* @author pigiuz
*
*/
public class AutowiringObjectBase
{
private var _iocFacade:IIocFacade;
public function AutowiringObjectBase()
{
_iocFacade = Facade.getInstance() as IIocFacade;
autoWire();
}
private function get container
():IConfigurableApplicationContext
{
return _iocFacade.container;
}
private function autoWire():void
{
var typeDescription:XML = describeType(this);
for each (var metaDataNode:XML in
typeDescription..metadata)
{
if (metaDataNode.attribute("name") == "Autowired")
{
var host:String;
var chain:String;
var propertyNode:XML = metaDataNode.parent();
var property:String = propertyNode.@name.toString
();
trace("Found Autowired property: " + property);
var objectName:String = property;
var autowireByType:Boolean = true;
for each (var arg:XML in metaDataNode.arg)
{
if (arg.attribute("key") == "host")
{
host = arg.attribute("value")
}
else if (arg.attribute("key") == "chain")
{
chain = arg.attribute("value");
}
else if (arg.attribute("value") == "byName")
{
autowireByType = false;
}
}
if (autowireByType)
{
if (host && chain)
{
// CHAINED AUTOWIRE
trace("Autowiring: " + property + " in " +
this + " from " + host + "." + chain);
var hostObject:Object = container.getObject
(host);
if (hostObject)
{
this[property] = hostObject[chain];
}
}
else
{
// AUTOWIRE BY TYPE
var clazz:Class = ClassUtils.forName
(propertyNode.@type.toString());
var objectNames:Array =
container.getObjectNamesForType(clazz);
if (objectNames.length == 1)
{
objectName = objectNames[0];
}
trace("Autowiring by type: " + property +
" in " + this);
this[property] = container.getObject
(objectName);
}
}
else
{
// AUTOWIRE BY NAME
trace("Autowiring by name:" + property + " in
" + this);
this[property] = container.getObject
(objectName);
}
propertyNode = null;
host = null;
chain = null;
}
metaDataNode = null;
}
// dispose describetype
typeDescription = null;
}
}
}
you can find some more explanations in this post on my blog:
http://www.flashfuck.it/2010/01/21/spring-actionscript-autowire-objects-not-defined-in-context/
is there any better way to do this, or any issues generated by doing
this?
byez
Piergiorgio Niero
I left a comment on your blog regarding your question, hope it helps a
little.
cheers,
Roland
On Jan 22, 2:33 pm, Piergiorgio Niero <piergiorgio.ni...@gmail.com>
wrote:
> var property:String = propertyNo...@name.toString
> ();
> trace("Found Autowired property: " + property);
> var objectName:String = property;
> var autowireByType:Boolean = true;
>
> for each (var arg:XML in metaDataNode.arg)
> {
> if (arg.attribute("key") == "host")
> {
> host = arg.attribute("value")
> }
> else if (arg.attribute("key") == "chain")
> {
> chain = arg.attribute("value");
> }
> else if (arg.attribute("value") == "byName")
> {
> autowireByType = false;
> }
> }
> if (autowireByType)
> {
> if (host && chain)
> {
> // CHAINED AUTOWIRE
> trace("Autowiring: " + property + " in " +
> this + " from " + host + "." + chain);
> var hostObject:Object = container.getObject
> (host);
> if (hostObject)
> {
> this[property] = hostObject[chain];
> }
> }
> else
> {
> // AUTOWIRE BY TYPE
> var clazz:Class = ClassUtils.forName
> (propertyNo...@type.toString());
> var objectNames:Array =
> container.getObjectNamesForType(clazz);
> if (objectNames.length == 1)
> {
> objectName = objectNames[0];
> }
> trace("Autowiring by type: " + property +
> " in " + this);
> this[property] = container.getObject
> (objectName);
> }
> }
> else
> {
>
> // AUTOWIRE BY NAME
> trace("Autowiring by name:" + property + " in
> " + this);
> this[property] = container.getObject
> (objectName);
> }
> propertyNode = null;
> host = null;
> chain = null;
> }
> metaDataNode = null;
> }
> // dispose describetype
> typeDescription = null;
> }
>
> }
>
> }
>
> you can find some more explanations in this post on my blog:http://www.flashfuck.it/2010/01/21/spring-actionscript-autowire-objec...
--
You received this message because you are subscribed to the Google Groups "springactionscript-dev" group.
To post to this group, send email to springactio...@googlegroups.com.
To unsubscribe from this group, send email to springactionscrip...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/springactionscript-dev?hl=en.
while your solution works, there are however a few points of criticism
I have.
First of all, having to inherit from a single monolithic base class to
handle annotated
injections might be feasible in a small project, it doesn't scale very
well. You'd end up
with a whole bunch of base classes that basically all do the same
thing, expose the
application context to its instance. Plus the Facade.getInstance()
invocation is something
you'd want to get rid of as soon as possible since this tightly
couples your code to a singleton
which makes it harder to unit test.
I will add however that the current incarnation of Spring Actionscript
(v0.8.1) doesn't offer you
a mechanism that could make things workable for you. However, I'm
thinking of adding a new
method to the application context: getInstance(class:Class);
This method could instantiate the specified class and pass it directly
into the wire() method of the
context, that way all injections will be performed based on its
annotations again.
Your code would end up looking like this:
for (var i:int=0;i<n;i++){
applicationContext.getInstance(MyAutowiringClass);
}
Does anyone else on the list have any ideas on this? Please feel free
to chime in...
Would getInstance() be a suitable name? Or would createInstance() be
better?
cheers,
Roland
On 22 jan, 15:09, Piergiorgio Niero <piergiorgio.ni...@gmail.com>
wrote:
> > For more options, visit this group athttp://groups.google.com/group/springactionscript-dev?hl=en.
I've added this method to the IObjectFactory interface:
public function createInstance(clazz:Class, constructorArguments:Array
= null):*;
your code would now look like this:
for (var i:int=0;i<n;i++){
applicationContext.createInstance(MyAutowiringClass);
}
And you no longer will need the base class to handle the injections.
Changes are available in the trunk.
On 25 jan, 10:18, Piergiorgio Niero <piergiorgio.ni...@gmail.com>
wrote:
I follow your interesting thread and, for better understand the way to
use springas, i have some questions:
- the vantage of using createInstance() method is that the
"MyAutowiringClass" doesn't need to be defiend in the application
context?
- the autowired properties of MyAutowiringClass don't need to be
defiend in the application context?
- doesn't createInstance() couple the MyAutowiringClass with the
factory class?
In a similar scenario i implement my factory class with
IApplicationContextAware interface in order to use the
IApplicationContext.getObject; of course my objects are defined in the
context with lazy-init attribute set to true and it cant be seen as a
vantage when you have to manage many object.
Thanks for answers and suggestions.
Paolo
On 3 Feb, 12:10, Piergiorgio Niero <piergiorgio.ni...@gmail.com>
wrote:
> ...
>
> leggi tutto
I follow your interesting thread and, for better understand the way to
use springas, i have some questions:
- the vantage of using createInstance() method is that the
"MyAutowiringClass" doesn't need to be defiend in the application
context?
- the autowired properties of MyAutowiringClass don't need to be
defiend in the application context?
- doesn't createInstance() couple the MyAutowiringClass with the
factory class?
In a similar scenario i implement my factory class with
IApplicationContextAware interface in order to use the
IApplicationContext.getObject; of course my objects are defined in the
context with lazy-init attribute set to true and it cant be seen as a
vantage when you have to manage many object.
Thanks for answers and suggestions.
Paolo
On 3 Feb, 12:10, Piergiorgio Niero <piergiorgio.ni...@gmail.com>
wrote:
you're correct in your first two assumptions, the createInstance()
method allows you
to create an instance of a specified Class that has been annotated
with [Autowired] metadata.
For this class there does not need to be an ObjectDefinition present
in the container, since
all injections are defined in the metadata.
I don't agree with the last point though, I don't believe the
MyAutowiringClass class would be tightly
coupled to the factory. Coupled to a certain extent, yes, but
loosely :) The only coupling to Spring
Actionscript would be the metadata, but there's nothing from stopping
a different library from interpreting
the exact same metadata and performing the injections.
Using the metadata is indeed more of a coupling between class and
factory then using pure XML based
object definitions. There's proponents and opponents of both ways,
Spring Actionscript just offers them both
so everybody stays happy :)
cheers,
Roland
> ...
>
> read more »
regards
paolo
> ...
>
> leggi tutto
--
You received this message because you are subscribed to the Google Groups "springactionscript-dev" group.
To post to this group, send email to springactio...@googlegroups.com.
To unsubscribe from this group, send email to springactionscrip...@googlegroups.com.
while I agree that it serves to be researched to be able to define all
types of dependency in Metadata, I do not
agree that defining your dependencies in XML is a strict coupling of
your classes. It might a coupling of
your DEPENDENCIES, but that is a different discussion :)
The primary advantage of defining your dependencies in XML is that tey
can be changed without having to
re-compile your application, in some cases this can prove incredibly
useful. The XML is not necessarily
coupled to one implementation of an application context, just like the
metadata is not coupled to a specific
implementation.
Piergiorgio, in your case, defining your dependencies in metadata is
only a *different* way of doing this
compared to creating object definitions for them, either way, these
dependencies need to be defined *somewhere*. :)
But like I said, being able to completely define dependencies in
metadata sounds like a viable plan, its not easy
I must say, the component scan mechanism already does this to a
certain extent. This has proved to be quite slow
though, plus I recently noticed that the class name extraction
functionality seems to be throwing errors in Flex4
generated swf's. So for now, it's still very much prototypical :)
Anyways, let's be clear about one thing, this functionality will not
make it for the version 1.0 release.
But, after that, it is certainly an avenue we will explore further,
since its very obvious that there are metadata fans and
XML fans alike, and we would like to keep everyone happy :)
I will create a JIRA ticket for this so it will end up on the roadmap.
thank you bother for your input!
cheers,
Roland
On Feb 5, 10:02 am, Piergiorgio Niero <piergiorgio.ni...@gmail.com>
> ...
>
> read more »
Ok, i'm agree. But you depend on context.xml to define all the common
class/properties that others classes pick up by annotations. is it
correct? or i miss something?
I think it can be very useful when you have to factory many different
types that share common object (model, manager, ecc), dont you?
Sì sono italiano... se ti fa piacere eventualmente mi piacerebbe
scambiare qualche parere anche in lingua (sono un po' duro di
comprendonio e non vorrei intepretare male o essere intepretato
male :)
Paolo
> ...
>
> leggi tutto
--
You received this message because you are subscribed to the Google Groups "springactionscript-dev" group.
To post to this group, send email to springactio...@googlegroups.com.
To unsubscribe from this group, send email to springactionscrip...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/springactionscript-dev?hl=en.
On 5 Feb, 10:57, Piergiorgio Niero <piergiorgio.ni...@gmail.com>
wrote:
> ...
>
> leggi tutto