Parsley’s Constructor Based Injection [InjectConstructor]

Implementing Constructor based Injection:

Constructor based injection in Parsley can be achieved using [InjectConstructor] metadata tag. It provides us with cleanest injection style as per encapsulation because it allows you to create immutable classes.

When we say its a constructor based injection, doesn’t that mean the metadata tag has to be placed on the constructor ?

Here is what I am trying to say:

package com.xyz{
     public class abc{
         [InjectConstructor] 
         public function abc(){
             }
    }
}

But, unfortunately the Flash Player currently ignores metadata tags placed on constructors you have to place a [InjectConstructor] tag on the class declaration to tell Parsley to perform Constructor Injection.

package com.bookstore.actions { 
 [InjectConstructor] 
 class LoginAction { 
 private var service:LoginService; 
 private var manager:UserManager;   
 function LoginAction (service:LoginService, manager:UserManager = null) { 
 this.service = service; 
 this.manager = manager; 


}

Constructor injection selects the dependencies based on the parameter types. This means that it only works for dependencies where you know that the Context will always contain at most one object with a matching type. It is also good practice to use interfaces as parameter types so that you can switch implementations in the configuration without modifying the class.

Using interfaces:

package com.bookstore.actions { 
 [InjectConstructor] 
 class LoginAction { 
 private var service:ILoginService; 
 private var manager:IUserManager;   
 function LoginAction (service:ILoginService, manager:IUserManager = null) { 
 this.service = service; 
 this.manager = manager; 


}

In the above code, parsley framework container throws an error if it does not contain an object of type LoginService, but it will simply silently ignore the second parameter if the Context does not contain an object of type UserManager.

Configuring Constructor based injection:

As MXML compiler generates the object creation code and parsley only gets hold of the object after it was instantiated to perform additional configuration, one cannot directly use simple MXML tags for configuration.

<Objects xmlns:fx="http://ns.adobe.com/mxml/2009" 
 xmlns="http://www.spicefactory.org/parsley" 
 <fx:Script> 
 <![CDATA[ import com.bookstore.actions.*; ]]> 
 </fx:Script>
 <fx:Declarations> 
 <Object type="{LoginAction}"/>
 </fx:Declarations> 
</Objects>  

Here is how we pass in the constructor args:

<parsley:Objects xmlns:parsley="http://www.spicefactory.org/parsley">
    <fx:Declarations>
          <!-- Configuring Login Action -->
          <parsley:Object  id="loginAction" type="{LoginAction}">    
             <parsley:ConstructorArgs>           
                <parsley:ObjectRef  idRef="userManager"/>             
                <fx:String>login</fx:String>
             </parsley:ConstructorArgs>
           </parsley:Object>

           <!-- Configuring User Manager -->
           <parsley:Object  id="userManager" type="{UserManager}">    
             <parsley:ConstructorArgs>           
                <fx:String>administrator</fx:String>
             </parsley:ConstructorArgs>
           </parsley:Object>
     </fx:Declarations>
</parsley:Objects>

When using Parsley’s Object tag it’s the framework that is responsible for instantiating the object so that Constructor Injection can be performed.

There are no restrictions when you are using XML configuration.

Source: http://www.spicefactory.org/parsley/docs/2.4/manual/injection.php

Advertisements

Firefox and Flash

The new FireFox version 10.0.1 is changing the user-settings for how Plugin Failures are handled. Here is the step by step instructions to change the firefox plugins:

  • Open Firefox
  • Type About:Config in the URL
  • Filter by ‘plugins’
  • Verify:

                            dom.ipc.plugins.enabled:false

                            dom.ipc.plugins.timeoutSecs:-1

Note: For knowing all the Enabled Plugin’s on firefox browser, just hit about:plugins.

Hope it helps !!!

Differences between [Inject] and [FastInject] tags

In order to illustrate the difference between [Inject] and [FastInject] we first need to know the difference between describeType and describeTypeJSON functions.

describeType:  The describeType() method returns an xml dump that contains all the details you’d ever need to know about any object that is passed in as a parameter. This method implements the programming concept of reflection API for the ActionScript language.

Ex: trace(flash.utils.describeType(flash.display.MovieClip));

Note: describeType() only shows public properties and methods, and will not show properties and methods that are private, package internal or in custom namespaces. If you need only to traverse an object’s inheritance hierarchy and do not need the other information provided by describeType(), use the getQualifiedClassName() and getQualifiedSuperclassName() functions instead.

More on this topic at http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/package.html#describeType()

describeTypeJSON:  With this  method it’s possible to retrieve reflection data as an object and to filter certain types of information using the constants.

HIDE_NSURI_METHODS = 1
INCLUDE_BASES = 2
INCLUDE_INTERFACES = 4
INCLUDE_VARIABLES = 8
INCLUDE_ACCESSORS = 16
INCLUDE_METHODS = 32
INCLUDE_METADATA = 64
INCLUDE_CONSTRUCTOR = 128
INCLUDE_TRAITS = 256
USE_ITRAITS = 512
HIDE_OBJECT = 1024
FLASH10_FLAGS = 1535

Ex:
package avmplus
{
    public function getInterfaces(object:*):Array
    {
        return describeTypeJSON(object, INCLUDE_TRAITS | INCLUDE_INTERFACES).traits.interfaces;
    }
}

Note:  The describeTypeJSON is defined in the avmplus.* package and supported for Flash Player 10.1

More on this topic at http://www.tillschneidereit.de/2009/11/22/improved-reflection-support-in-flash-player-10-1/

[Inject] v/s [FastInject]:

Parsley has the ability of reflection API which reflects on all managed objects and reflection of components which is very expensive operation due to numerous number of properties,methods and events. Which means that Parsley   2.1 and below uses describeType() method on all of its manages objects. [Inject] tag uses the describeType() method to introspect its managed objects.

Introduced in Parsley 2.2, the [FastInject] tag is the key to the performance optimization. [FastInject] uses the describeTypeJSON() method which is faster than describeType(). Note that the impact of reflecting huge UIComponents is still high. Parsley maintains an internal reflection cache, so that each class is only processed once, but if you are using a high number of different component classes this may not help much.In a smaller application this effect is negligible but its a concern for larger applications.

<parsley:FastInject property="model" type="{MyPanelPM}" /> 
 
<parsley:FastInject injectionComplete="init();"> 
 <parsley:Inject property="model" type="{MyPanelPM}"/> 
 <parsley:Inject property="status" type="{MyApplicationStatus}"/> 
</parsley:FastInject>
 
Action Script:
function MyView () { 
 FastInject .view(this) 
 .property("pm") 
 .type(MyViewPM) 
 .complete(injectionComplete) 
 .execute(); 

 
private function injectionComplete () : void { /* ... */ }

Corrections:  describeType() and describeTypeJSON() are not included in Parsley framework, they are part of avmplus package of the Flash Player. describeTypeJSON is provided in Flash Player 10.1 and above.

reflection in fp 10.1

If the user runs the Flex Application built with Parsley framework against Flash Player’s versions 10.1 and above, Parsley intelligently uses the faster describeTypeJSON() and if the application is run against Flash Player versions below 10.1, Parsley uses  the slower describeType()

In reality, FastInject neither uses describeType() nor describeTypeJSON(). FastInject is used for injecting a managed object from the nearest Context in the view hierarchy into a view without reflecting on the view. This way the FastInject  retrieves a particular object from the IoC Container without actually getting wired to it to avoid the cost of reflection and hence its fast.

Sources:

http://www.spicefactory.org/parsley/docs/2.4/manual/?page=view&section=intro
http://www.tillschneidereit.de/2009/11/22/improved-reflection-support-in-flash-player-10-1/
http://www.scottgmorgan.com/blog/index.php/2007/10/22/say-hello-to-my-little-friend-describetype/