Runtime Injection

Tejpal Borkar's Avatar

Tejpal Borkar

11 Jun, 2013 01:02 PM

Hi... I want to inject a singleton class object in my application at runtime. is it possible with robotlegs...?

  1. Support Staff 1 Posted by Ondina D.F. on 11 Jun, 2013 04:16 PM

    Ondina D.F.'s Avatar

    Hello Tejpal,

    Hopefully, I understood your question correctly: you want to inject a class for which you haven’t provided a mapping in your context, right?

    In this case, you have to map the class right before the injection occurs. Without a mapping (rules) the Injector cannot handle the injection, as you probably know.

    Let’s say you had 2 Models, SomeModel and AnotherModel, both implementing an interface - IModel.
    Depending on some conditions, you’d want to switch between the 2 models inside a command. In the command you’d inject the interface:

    [Inject] public var model:IModel;

    Before triggering the command, you’d have to map the model that you want to be used, like this:

    injector.mapSingletonOf(IModel, SomeModel);

    or

    injector.mapSingletonOf(IModel, AnotherModel);

    Let us know whether this answers your question or not. If it doesn’t, then please give us more details about what you mean by “runtime injection”.

    Ondina

  2. 2 Posted by Tejpal Borkar on 12 Jun, 2013 05:08 AM

    Tejpal Borkar's Avatar

    Thank you very much.. but my exact problem is , i wanted to pass some argument to the injecting class so that the injection will be done depending on the parameter which i passed...
    suppose i have a
    class Base{
    }
    class Child extends Base{

    }
    class Try{    [Inject ( id="Passed Argument")] public var b:Base;
        [Inject ( id="Passed Argument")] public var c:Child;
    }
    class C{    [Inject (id="can I Pass some Argu. Here")]  var t:Try;

    }

    I want to pass parameters from Class C to Try Class. Then the Try Class injects Base and Child Class Depending on these parameters.. So Is it possible in Robotlegs?

    Thanks and Regards

    TEJPAL B. BORKAR

    [email blocked]

    mb. no. 9096865304

  3. Support Staff 3 Posted by Ondina D.F. on 12 Jun, 2013 02:50 PM

    Ondina D.F.'s Avatar

    You’re welcome, Tejpal.

    [Inject(id = "can I Pass some Argu. Here")] var t:Try;

    No, you can’t pass arguments like this.
    You either pass the properties by accessing an API of the class that needs them, or you inject them in every class, for example as a VO.

    Then the Try Class injects Base and Child Class Depending on these parameters.

    Personally, I don’t know of a way of making the injection conditional in robotlegs version 1. Maybe I’m missing something….

    SwiftSuspenders version 2 introduced optional injection, but I’m not sure whether the latest rl1 supports SwiftSuspenders 2.

    Anyway, with optional injection, you could have something like this:

    [Inject (optional=true)] public var childOne:ChildOneClass;

    [Inject (optional=true)] public var childTwo:ChildTwoClass;

    If, for example, there is only a mapping for childOne, injector.mapSingleton(ChildOneClass);, and none for childTwo, you could check if childTwo is null before trying to use it.
    Say, in your class C you’d map the class that you wanted to be used inside Try. Then in class Try you’d check which one is available.
    Of course you’d have to unmap it manually, if need be.

    In robotlegs version 2 you could make use of the new features, guards and hooks, to make decisions depending on some conditions.

    In my example bellow, there is a GrandparentClass (like your class C) that has a ParentClass (class Try) injected into it. ChildOneClass and ChildTwoClass are like your classes that you wanted to be injected into the Try class.

    GrandparentClass sets a property like this:
    someVO.someCondition = "one";

    Then it calls parentClass.switchChildren();
    SomeVO has been injected into ParentClass, so ParentClass will have access to someVO.someCondition.

    guardsApprove([approve]) will check against a condition inside of the aprove() method, which will return true or false.

    So, if someVO.someCondition==”one”, the guards return true, and ChildOneClass will be instantiated. Otherwise ChildTwoClass will be instantiated. SomeVO has been injected into ChildOneClass and ChildTwoClass as well, and they can set or get its properties.

    Guards and hooks can be used in various ways. This is just a simple example.

    SomeVO

    
        public class SomeVO
        {
            private var _someCondition:String;
            
            private var _someProperty:String;
    
            public function SomeVO()
            {
            }
    
            public function get someProperty():String
            {
                return _someProperty;
            }
    
            public function set someProperty(value:String):void
            {
                _someProperty = value;
            }
    
            public function get someCondition():String
            {
                return _someCondition;
            }
    
            public function set someCondition(value:String):void
            {
                _someCondition = value;
            }
        }
    

    Grandparent

        public class GrandparentClass
        {
            [Inject]
            public var parentClass:ParentClass;
    
            [Inject]
            public var someVO:SomeVO;
    
            public function GrandparentClass()
            {
            }
    
            public function setSomeParams():void
            {
                someVO.someCondition = "one";
                parentClass.switchChildren();
            }
        }
    

    ParentClass

    
        public class ParentClass
        {      
            [Inject]
            public var someVO:SomeVO;
    
            [Inject]
            public var injector:IInjector;
    
            public function ParentClass()
            {
            }
    
            public function switchChildren():void
            {
                someVO.someProperty = "Your parent says hi";
                if (guardsApprove([approve]))
                {                             
                    applyHooks([ChildOneClass], injector);
                }
                else
                {
                    applyHooks([ChildTwoClass], injector);
                }
            }
    
            public function approve():Boolean
            {
                return someVO.someCondition == "one";
            }
        }
    

    ChildOneClass

        public class ChildOneClass
        {
    
            [Inject]
            public var someVO:SomeVO;
    
            public function ChildOneClass()
            {
            }
    
            public function hook():void
            {
            //do whatever you need to do in here
                trace("ChildOneClass.hook() " + someVO.someCondition);
            }       
        }
    

    ChildTwoClass

     public class ChildTwoClass
        {
            
            [Inject]
            public var someVO:SomeVO;
    
            public function ChildTwoClass()
            {
            }
                    
            public function hook():void
            {
                //do whatever you need to do in here
                trace("ChildTwoClass.hook() " + someVO.someProperty);
    //will trace Your parent says hi, 
    //set in ParentClass.switchChildren
            }
        }
    

    Cheers,
    Ondina

  4. 4 Posted by Tejpal Borkar on 13 Jun, 2013 12:51 PM

    Tejpal Borkar's Avatar

    Thanks sir..Its absolutely  correct sir... but i just want to make very few changes in my existing application. so suggest some solution by using naming injection..in my application its some what like as follows..
    class Try{
    some function{    // here i want to pass parameters to Someclass to inject its reference variables
    }
    }
    class SomeClass{    [Inject (name="passed par")] var b:Base;
    // and many more Inject variables to inject according to the parameters }
    in context class
    lets say 
    class MyContext{function    startup()
    {   injector.mapSingleton(SomeClass, "InjectBase");
       injector.mapSingleton(SomeClass, "InjectChild");}
    }

    Thanks and Regards

    TEJPAL B. BORKAR

  5. Support Staff 5 Posted by Ondina D.F. on 13 Jun, 2013 02:49 PM

    Ondina D.F.'s Avatar

    Thanks sir..Its absolutely  correct sir.

    You’re welcome!
    Just for your information: I’m a woman. ;)

    If you map your class like this:

    injector.mapSingleton(SomeClass, "InjectChild");
    injector.mapSingleton(SomeClass, " InjectBase");

    then you’ll have to inject it like this:

    [Inject (name=“InjectChild“)] public var child:SomeClass;

    [Inject (name=“InjectBase“)] public var base:SomeClass;

    So, you’ll have 2 instances of SomeClass.

    I don’t see how this would solve your problem.

    You cannot use the „name“ inside of the Inject tag for passing parameters!!!
    The name is used internally by the Injector. It’s kind of an id that helps the Injector to differentiate between injection points of the same type.

    Using interfaces:

    injector.mapSingletonOf(IModel, AnotherModel, "anotherModel");
    injector.mapSingletonOf(IModel, SomeModel, "someModel");
    

    then you can inject the interface like this:

    [Inject (name="someModel")]
    public var someModel:IModel;//this would be an instance of SomeModel
    
    [Inject (name="anotherModel")]
    public var anotherModel:IModel;//this would be an instance of AnotherModel
    

    Another option would be to use the injector to retrieve an instance of a mapped class, instead of injecting it:

    private var model:IModel;
    
    if(someCondition)
       model = injector.getInstance(IModel, "someModel");
    else
       model = injector.getInstance(IModel, "anotherModel");
    

    but i just want to make very few changes in my existing application.

    Well, I can’t see your code, so I can’t know what exactly is to be done to solve your problem with the minimum amount of effort and changes.

  6. Support Staff 6 Posted by Ondina D.F. on 21 Jun, 2013 10:13 AM

    Ondina D.F.'s Avatar

    Feel free to reopen this discussion, if you're still having problems. Please open new threads for new issues.

  7. Ondina D.F. closed this discussion on 21 Jun, 2013 10:13 AM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac