Constructor Injection - double constructor call

jiri's Avatar

jiri

18 May, 2010 09:35 AM

Hello,

I have a question about some behavior I am not really grasping. The case is as follows, when I use constructor injection and I put a trace statement in the constructor of the class, it gets called twice.
Here is how I setup a rule, in the main context.

injector.mapSingletonOf( ISettings , Settings );
injector.mapSingleton( BaseModel );
var bm:BaseModel = injector.instantiate( BaseModel );

And this is the subject class. I noticed that there is no difference wheter I add the [Inject] tag or not on the top of the BaseModel class. In both cases the injection the result is the same which I find odd. Shouldn't I have to add the [Inject] tag or is it due to the fact that I use the injector.instantiate in the context that either way it works?

public class BaseModel extends Actor
{

    private var settings:ISettings;
    
    public function BaseModel(settings:ISettings)
    {
        this.settings = settings;
        trace("settings is null ? " , settings);
    }
}

This then outputs:

settings is null ? null
settings is null ? [object Settings]

Also when I add a [PostConstruct] in the BaseModel, it is not called. I use the Robotlegs SWC v1.1.0 beta 3

  1. Support Staff 1 Posted by Shaun Smith on 18 May, 2010 09:43 AM

    Shaun Smith's Avatar

    Hi Jiri,

    There are two issues here:

    1. injector.instantiate will always return a new instance - regardless of how you've mapped it. What you're probably after is injector.getInstance which will give you an instance based on the mappings you've made. #getInstance should be available in v1.1.0b3 - if it isn't then try v1.1.0b7.

    2. There is a bug with the Flash Player when it comes to constructor injection - as a workaround, a dummy instance must be constructed before the constructor arguments can be determined. See: https://bugs.adobe.com/jira/browse/FP-2962

    Sorting out 1 should fix your issue. Let me know if it doesn't.

  2. 2 Posted by jiri on 19 May, 2010 11:29 AM

    jiri's Avatar

    Thank you for the reply. I tried solution #1, but no change in behaviour, I still get this as output:

    settings is null ?  null
    Settings model instantiated
    settings is null ?  [object Settings]
    init is called
    

    To be sure, I post the BaseModel. I am also surprised that I don't need to put the [Inject] tag in the BaseModel. I was under the assumption that this was necessary?

    package model
    {
        public class BaseModel
        {
    
            private var settings:ISettings;
            
            public function BaseModel(settings:ISettings)
            {
                this.settings = settings;
                trace("settings is null ? " , settings);
            }
            [PostConstruct]
            public function init():void{
                trace("init is called")
            }
        }
    }
    

    And this is what I placed in the context

        injector.mapSingletonOf( ISettings , Settings );
        injector.mapSingleton( BaseModel );
        injector.getInstance( BaseModel );
    

    I really dont understand what it is I am doing wrong. I checked with the Profiler and there is 1 instance of BaseModel, but a cumulative number of 2. I would like to figure this out, because I don't the extra impact of creating two instances. It seems that it is due to the constructor injection and the mentioned bug #2. Possibly I will resort to property injection instead.

  3. Support Staff 3 Posted by Shaun Smith on 19 May, 2010 04:57 PM

    Shaun Smith's Avatar

    Using constructor injection will always result in an extra (dummy) instance being created the first time that the IoC container (SwiftSuspenders by default) encounters such a class - due to the bug mentioned. As you noticed, the dummy instance is thrown away after the constructor arguments have been determined, and the result is cached. There is very little overhead with this workaround (unless you do a lot of work in the constructor, which is generally a bad idea anyway).

  4. Support Staff 4 Posted by Till Schneidere... on 19 May, 2010 05:16 PM

    Till Schneidereit's Avatar

    I didn't test this yet, but the bug has been marked as fixed with a
    comment indicating that the fix should be available in a public
    player. Presumably, this means that the fix is contained in the
    current public beta of 10.1.

    If that's the case, then SwiftSuspenders will automatically do the
    right thing and not create a dummy instance of the class: That only
    happens if all of the constructor's parameters don't have types.

  5. Support Staff 5 Posted by Shaun Smith on 19 May, 2010 05:21 PM

    Shaun Smith's Avatar

    Awesome stuff - I was wondering how the fixed player would be integrated. Seems like it'll just work. Nice one!

  6. Shaun Smith closed this discussion on 20 Jun, 2010 04:15 PM.

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