Injection fails into non-singleton model
I am trying to inject a signal into a model that is not a singleton.
in my context I have:
signalCommandMap.mapSignalClass(SetBrailleFocus, BrailleSetFocusCommand);
In the model (which is called TabManager) I have:
[Inject] public var setBrailleFocus:SetBrailleFocus;
and then later:
setBrailleFocus.dispatch(boss);
Whenever execution reaches that last line of code, I get "Cannot access a property or method of a null object reference."
I have tried
injector.mapClass(TabManager, TabManager);
even though that doesn't make sense because I'm not trying to inject TabManager into anything.
I have also tried making TabManager extend actor.... I'm grasping at straws, I guess.
What am I missing, here? It all seems straightforward enough...
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
Support Staff 1 Posted by Till Schneidere... on 10 Nov, 2011 03:19 AM
How are you creating the instances of TabManager?
For dependencies to actually be injected, you have to either use the
injector to create the instance itself, or use injectInto to satisfy
the dependencies afterwards:
var tabManager : TabManager = injector.instantiate(TabManager);
or
var tabManager : TabManager = new TabManager();
injector.injectInto(tabManager);
The injector can't magically find out that there's a new instance with
an [Inject] tag being created somewhere, so you have to help it a bit
;)
2 Posted by ndechman on 10 Nov, 2011 04:53 AM
Thanks for your response!
That makes perfect sense, and I had suspected it, but I do not know how to get the injector out to where these things are being instantiated.
Almost every view instantiates one, and the instantiation looks like:
tabManager = new TabManager(this, cancelationButton);
So, I guess that is the question, now.... How do I get the injector to run in a view?
I could make a wrapper for TabManager, I suppose... then would that wrapper have to extend SignalContext?
3 Posted by ndechman on 11 Nov, 2011 02:12 AM
I could really use an answer to this....
Passing injector from context to controller to view seems anathema to the aims we're trying to achieve with dependency injection.
And there are so many views I'd have to have that injector evrywhere!
Support Staff 4 Posted by Stray on 11 Nov, 2011 10:31 AM
Hi there - I agree, passing it around manually would be a mess. But the mess is partly there because you're creating something that's not really a view inside your other views.
You've broken the MVC encapsulation (or at least bent it) and so the Robotlegs MVCS trousers aren't automatically set up to deal with this situation.
Luckily Robotlegs is pretty flexible.
There are several ways of approaching this:
1) To re-architect - because it feels to me like a broken architecture is the problem. But this is pretty radical. So, let's assume that you're not going to do that.
2) To use the viewMap and wire the TabManager for injection, assuming that it's a view object and lands on the stage - if it isn't then that's not going to work. Even if it is, using view injection and mediators in RL1 together incurs a serious performance hit.
3) To use a conventional static accessor to get to the Signal (at least until you figure out something else).
4) If TabManager is a display object then you can always mediate it and use the mediator to pass the signal.
5) Assuming that it's not a display object, you could mediate the objects that are creating TabManager and pass the signal (not the injector) into the mediator, and set up your TabManagers there.
6) Better than 5 - make a little factory (Singleton) that creates the TabManagers where they are required. Mediate the views that need them. Use the factory in the mediator. The tabManagerFactory should track whether one has already been created or whether this is a new request, and either supply the new one or not:
Basically creating an application-level model inside multiple views in your view tier is a non-conventional approach to MVC. You would probably be better simply dispatching a custom event from your views, not using signals, and then the custom event can bubble up and be caught in a mediator and dealt with at the application level.
Signals are great for many situations - but this is a situation in which I think Events win, because bubbling avoids so many wiring problems.
hth,
Stray
5 Posted by ndechman on 11 Nov, 2011 01:02 PM
Haha! I did call this thing a model in my original post! I think I did that because I had just spent several hours reading every forum I could find on injection, ending up with searching something or other about model injection.
This is not a model, this is probably more correctly referred to as a controller utility. It handles tab order and whatnot for views.
But, that said, it is a controller-ish thing that is instantiated from a view instead of vice versa, so it is not quite perfect MVCS. It should be instantiated from the mediator.
This makes me doubly appreciative of your response, Stray, and also gives me respect for this community. Where else could I have expected anything but an unhelpful snarky response? But instead you took the time not only to point out the error in my post and the ideal correct solution given that error, but also to provide very helpful solutions in case I did not want to correct the apparent problem.
Thanks again!
Support Staff 6 Posted by Stray on 11 Nov, 2011 01:17 PM
No problem!
And thanks for expressing your appreciation - I'm now warm and fuzzy :)
If you run into problems implementing the solution you choose, shout again and we'll try to figure it out with you in more detail.
Sorry it took a little longer than normal to get you a fix as well - we're slightly distracted by building Robotlegs 2 at the moment, I'm glad you came back and asked again, as I had meant to respond to your second question yesterday and it had slipped my mind.
Cheers!
Stray
Ondina D.F. closed this discussion on 13 Nov, 2011 08:25 AM.