Broken injector or I'm doing something wrong
Took a basic hello world example and took it from there. I thought I had an idea about how this works but either I'm getting it wrong, or something is broken.
Two files,
public class IQTestContext extends Context
{
public function IQTestContext(stage:Stage)
{
trace(stage);
super(stage);
}
override public function startup():void
{
injector.mapValue(Stage, contextView);
var brawsar:FullBrowserStageMediator = new FullBrowserStageMediator();
injector.mapValue(FullBrowserStageMediator, brawsar);
injector.mapValue(RemoteConsoleModel, new RemoteConsoleModel());
// Map some Commands to Events
commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE, CreateBallCommand, ContextEvent, true);
commandMap.mapEvent(HelloFlashEvent.BALL_CLICKED, CreateBallCommand, HelloFlashEvent );
// Create a rule for Dependency Injection
injector.mapSingleton(StatsModel);
// Here we bind Mediator Classes to View Classes:
// Mediators will be created automatically when
// view instances arrive on stage (anywhere inside the context view)
mediatorMap.mapView(Ball, BallMediator);
mediatorMap.mapView(Readout, ReadoutMediator);
// Manually add something to stage
contextView.addChild(new Readout());
// And we're done
super.startup();
brawsar.konstraktar();
}
}
and the second,
public class FullBrowserStageMediator extends Actor
{
[Inject]
public var appStage:Stage;
public function FullBrowserStageMediator()
{
super();
}
public function konstraktar():void {
appStage.scaleMode = StageScaleMode.NO_SCALE;
appStage.align = StageAlign.TOP_LEFT;
}
}
The Inject tag is written using proper capitalization. It's a public variable, it's got a name that shouldn't cause name conflicts. The Stage is mapped before the Actor is created. The Flash IDE is set to export an SWC. The injected property is not used until after the constructor for it's parent class returns. Despite all that, the injection never happens and I have a null appStage regardless.
Tracing the stage object produces object Stage. It's definitely getting passed to the constructor. It's as if the injector fails to inject the Stage object.
I have no idea what I'm doing wrong. Please advise.
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
1 Posted by archont on 04 Oct, 2010 08:46 PM
Here's a snippet, I put some additional trace statements to verify if the Stage is really, really there.
override public function startup():void { trace(contextView); injector.mapValue(Stage, contextView); trace(injector.getInstance(Stage)); // ... }
All return object Stage. It appears the injection simply doesn't take place. Why is that?
2 Posted by Stray on 04 Oct, 2010 08:57 PM
Hi there,
You're creating the FullBrowserStageMediator in a conventional way - using new X() ... so it won't be injected into. Only classes which are instantiated by the framework (Commands, Mediators, classes mapped as Singletons etc) are automagically injected with their dependencies.
You could check out injector.instantiate()...
or even injector.injectInto(... )
Both of these would be helpful to you.
But - I'd say that this mediator should indeed be a mediator!
If you have FullBrowserStageMediator extend Mediator:
Then in your context do:
mediatorMap.mapView(ContextViewClass, FullBrowserStageMediator) /// I'm not sure what your ContextViewClass is - you should put that in here
and then instead of addressing the stage directly, do it via that contextView.
So you would have (in the FullBrowserStageMediator):
[Inject]
public var view:ContextViewClass;
and
override public function onRegister():void
{
view.stage.scaleMode = ... etc
// the code that is in your konstraktar function goes here
}
If you don't have access to the stage from contextView then just pass in and mediate a view class that does have access to the stage.
It might even be possible to map to the Stage directly and use the mediatorMap.createMediator() function - as Stage is never added to the Stage :)
I'm not sure about mediating Stage directly - I've not tried it.
Hopefully this is enough to get you back on track,
Let us know if you need more guidance,
Stray
3 Posted by archont on 04 Oct, 2010 09:09 PM
That makes a lot more sense - I was under the impression that injection works automatically. with all classes that use the tag. You also helped me understand a (glaring) conceptual error that I probably wouldn't have noticed.
I'll probably be using the injector.injectInto/instantiate methods for non-MVC object factories, as a way to relatively cleanly leverage SmartyPants in classes that won't use MVC but could use dependancy injection.
Thanks for a very informative, valuable and concise post!
4 Posted by Stray on 04 Oct, 2010 09:24 PM
Awesome!
We aim to meet your injection needs. ;)
If you do try to mediate the Stage directly let us know how that goes - I should try it myself but I'm a bit short on time.
Cheers,
Stray
5 Posted by archont on 04 Oct, 2010 09:44 PM
Manually mediating the Stage works as you said.
Apart from having to manually create a mediator, everything else works as intended. I haven't tested for any potential problems with events/signals, but I assume everything should work fine.
Stray closed this discussion on 10 Feb, 2011 05:52 PM.