injected model = null - without typo, it is mapped, not in constructor!
Hey there,
I know its a really common question and I know all the problems
most developers have with robotlegs injections.
and I also know the solutions. But now I dont know what to do.
I have a small class like this.
public class VehicleSpeed extends Signal
{
[Inject]
public var vehicleModel:VehicleModel;
public function VehicleSpeed(identifier:String)
{
super();
this.identifier = identifier;
}
public override function writeData(value:*):void
{
vehicleModel.vehicleSpeed = value;
}
}
the vehicleModel is always null. Why? I cant see any typo, it is
not called from the constructor and it is mapped in the main
context.
I hope there will be some help anywhere in this universe ;-)
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 Ondina D.F. on Nov 13, 2013 @ 03:51 PM
Hi,
I'm not sure what writeData() is overriding there and also how and when you call this method. If it's not called in the constructor of VehicleSpeed and the mappings are correct, then the injection should work.
Have you tried constructor injection like so:
Or, have you tried to see if the vehicleModel is also null in a posconstruct method?
Other than that, it is important how you instantiate VehicleSpeed. Are you doing this:
private var vehicleSpeed: VehicleSpeed = new VehicleSpeed();
or this:
injector.instantiate(VehicleSpeed); instead of injector.getInstance(VehicleSpeed);
?
If so, then please take a look at this discussion to find yet another discussion about injector.instantiate() :P
http://knowledge.robotlegs.org/discussions/questions/7134-eventmap-...
Let me know how it goes.
Ondina
2 Posted by Chris on Nov 13, 2013 @ 10:32 PM
Did you check your context class for errors or omissions?
3 Posted by iamable on Nov 14, 2013 @ 07:49 AM
hi,
unfortunately [PostConstruct] doesnt work in this class. I dont know why.
I think I have to tell you more about the structure:
So I have a Connect class receibing key value pairs from socket:
on data income it is searching through the SingalList holding all the signals (e.g. VehicleSpeed):
here VehicleSpeed is instantiated with new VehicleSpeed()
and last but not least the above VehicleSpeed extends the Class Signal and write the value from socket to any model:
4 Posted by iamable on Nov 14, 2013 @ 08:23 AM
I think the problem is the context class.
Until now I didnt mapped VehicleSpeed, SignalList and Signal.
Thatswhy I instantiated them with new.
I think because of that, injection is not possible and also [PostConstruct doesnt work. Am I right?
I don't really know how to map those classes.
In that way?
and then just inject them into the Connect and SignalList?
Unfortunately this is not working. The instance of VehicleSpeed in SignalList is now null.
Support Staff 5 Posted by Ondina D.F. on Nov 14, 2013 @ 08:35 AM
I'll take a closer look at the pasted code. There might be several issues with it.
First one I noticed is:
VehicleSpeed has to be created by the Injector in order to get its dependencies fulfilled.
With new VehicleSpeed() you create an instance that is in no way known by the Injector.
Why don't you just inject VehicleSpeed into that class? Or as mentioned in my previous post, you could get an instance like this:
vehicleSpeed: VehicleSpeed = injector.getInstance(VehicleSpeed);
But then you'd have to inject the injector into that class as well.
It would be easier (for me) to find all the problems, if you attached the project or a simplified version of it. Anyway, I'll report back.
Support Staff 6 Posted by Ondina D.F. on Nov 14, 2013 @ 08:36 AM
Oh, I see you wrote another post in the meantime:)
7 Posted by iamable on Nov 14, 2013 @ 08:42 AM
Thanks Ondina,
I tried out several things.
Now I [Inject] VehicleSpeed.
your suggestion vehicleSpeed: VehicleSpeed = injector.getInstance(VehicleSpeed); doesnt work.
injector isnt found. i also dont know why.
and in VehicleSpeed still the problem ofvehicleModel = null and no possible [PostConstruct]
Support Staff 8 Posted by creynders on Nov 14, 2013 @ 08:55 AM
Are you using the RL .swc or compiling from the source files?
If the latter, you need to add the following compiler argument:
keep-as3-metadata+=Inject, PostConstruct
9 Posted by iamable on Nov 14, 2013 @ 09:02 AM
i am using the swc
I found out the problem is this line:
injector.mapValue(VehicleSpeed, new VehicleSpeed("Vehicle_Speed"));
if I map a singleton without arguments everything works fine.
What can I do to map a class with arguments?
Support Staff 10 Posted by Ondina D.F. on Nov 14, 2013 @ 09:34 AM
Does this work?
11 Posted by iamable on Nov 14, 2013 @ 10:16 AM
sorry I dont understand your example.
I am searching for something like that:
in Context:
in SignalList:
but htis is not working
Support Staff 12 Posted by Ondina D.F. on Nov 14, 2013 @ 10:29 AM
This will be used for a constructor injection into VehicleSpeed.
Of course, you can map VehicleSpeed like this:
injector.mapSingleton(VehicleSpeed);
and identifier will be injected, as well.
I gave you the example with injector.instantiate(VehicleSpeed); because you asked how to use mapValue:
injector.mapValue(VehicleSpeed, new VehicleSpeed("Vehicle_Speed"));
with constructor arguments:)
As I said, it would be easier if you attached the relevant code, so I can run it in the debugger.
Support Staff 13 Posted by Ondina D.F. on Nov 14, 2013 @ 10:44 AM
Sorry, forgot to say that you need to add [Inject] in your Signal class(btw. can't you rename it??), for the injection to work:
See, it's hard to detect all the weak spots in your pasted code. A running example, reproducing your issues, would be the best, and less time consuming:)
In case you don't want other people to see your code,
I, or you, can make the discussion private while you're attaching the project, I'll download it, delete it from this discussion, and then mark the discussion as public again.
14 Posted by iamable on Nov 14, 2013 @ 10:56 AM
the problem is the project us much bigger than the part I posted here.
But I will try to create a small project with these important classes.
So lets make it private
Support Staff 15 Posted by Ondina D.F. on Nov 14, 2013 @ 10:58 AM
It's private now.
16 Posted by iamable on Nov 14, 2013 @ 11:25 AM
ok i created a small project
everything is working but adding new signals would be really complex.
I dont know if my structure is the best.
Very much before i had a simple switch-case in the Connect class for changing data in the model depending on the signal.
It was working but I want to uncouple the signals. I want just to create a new Class for every signal and add it to the signallist
Support Staff 17 Posted by Ondina D.F. on Nov 14, 2013 @ 11:32 AM
ok, I've dl-ed the project and deleted the attachment. I'll take a look at your code
till later..
Support Staff 18 Posted by Ondina D.F. on Nov 14, 2013 @ 12:53 PM
I made just a few changes. It works on my end.
I'm attaching the app. I'll comment in a few..
N.B. I changed SignalStructure-app.xml to work with air 3.9 You'll have to change it back to your version
19 Posted by iamable on Nov 14, 2013 @ 01:43 PM
ok thank you. file can be deleted.
could you please make some explanations for the SignalList and IdentifierVO?
How does this work for hundreds of signals?
Support Staff 20 Posted by Ondina D.F. on Nov 14, 2013 @ 02:21 PM
Yes, just a moment please... Long phone call..I'll be back soon..
Support Staff 21 Posted by Ondina D.F. on Nov 14, 2013 @ 02:45 PM
IdentifierVO is just a carrier class. You use it to transport strongly typed data from a place to another.
If you had something like this:
and then also:
and you'd want to inject them both somewhere, the injector would use the last defined rule, so you'd only see the value of anotherProperty in the injected class. To remedy this you'd have to use named injections:
and inject them like this:
With a VO you can avoid named injections, have someProperty and anotherProperty as properties of the VO and simply read/write the ones you need wherever you need them. If you decide to add or remove a property from the VO or change its data type, the injection itself into a certain class won't suffer. But, if you try to access a non-existent VO property, you get a compiler error immediately.
I don't know, because I can't understand the use case from the code I have in front of me.
Why do you need hundreds of signals? Maybe you need just one signal with different payloads? The payloads being also strongly typed VOs.
Where are you dispatching the signals? Who would listen for them?
Support Staff 22 Posted by Ondina D.F. on Nov 14, 2013 @ 03:05 PM
Maybe what you are after is the 'request-response' way of using signals?
If so, please read a few discussion on the topic, if you haven't already :)
http://knowledge.robotlegs.org/discussions/problems/213-no-subject
https://gist.github.com/Stray/664521
http://knowledge.robotlegs.org/discussions/problems/322-request-mod...
http://knowledge.robotlegs.org/discussions/questions/585-loading-da...
http://knowledge.robotlegs.org/discussions/problems/681-response-fr...
Support Staff 23 Posted by Ondina D.F. on Nov 14, 2013 @ 03:11 PM
May I mark this discussion as public by now?
24 Posted by iamable on Nov 14, 2013 @ 03:23 PM
Thank you so much for your help this day.
I found a new solution for my problem.
instead of passing the identifier into the constructor of every signal and comparing to key of incoming key from socket, I can save the instances of all signals in an dictionary together with the key.
Now I only have to compare to the keys of the Dictionary and call the method of the related Signal instance.
Support Staff 25 Posted by Ondina D.F. on Nov 14, 2013 @ 03:32 PM
No problem :)
Does this mean, we can consider the issue resolved and close the discussion?
Of course, you can re-open it later, when/if you have more questions, or open new threads for other problems.
26 Posted by iamable on Nov 14, 2013 @ 03:44 PM
yes its problem is solved :)
Ondina D.F. closed this discussion on Nov 14, 2013 @ 03:46 PM.