tag:robotlegs.tenderapp.com,2009-10-18:/discussions/robotlegs-2/8182-the-necessary-conditions-of-injection-to-workRobotlegs: Discussion 2018-10-18T16:35:53Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/300390332013-11-18T08:46:09Z2013-11-18T08:46:09ZThe necessary conditions of injection to work<div><p>Yes if you create MyClassB with injector.</p>
<p>so, instead of just doing new MyClassB() you would:</p>
<ol>
<li>injector.map(MyClassB)<br>
and then in some other class</li>
</ol>
<p>[Inject] public var myClassB:MyClassB;</p>
<p>or you could<br>
[Inject] public var injector:IInjector;</p>
<p>and then<br>
injector.instantiateUnmapped(MyClassB);</p>
<p>then, injector will provide MyClassB with all dependencies.</p>
<p>Note that you can use</p>
<p>injector.map(IMyClass).toSignleton(MyClass);</p>
<p>to achieve the same thing you did for IMyClass mapping;</p></div>matejtag:robotlegs.tenderapp.com,2009-10-18:Comment/300390332013-11-18T10:41:51Z2013-11-18T10:41:51ZThe necessary conditions of injection to work<div><p>Why I need to use <code>instantiateUnmapped</code>.Why I cannot
instantiate as I have wrote in my question? The rule of mapping is
defined below, isn't it?</p>
<p>var inst : IMyClass = new MyClass;<br>
injector.map(IMyClass ).toValue(inst);</p></div>naghekyantag:robotlegs.tenderapp.com,2009-10-18:Comment/300390332013-11-18T12:53:49Z2013-11-18T12:53:49ZThe necessary conditions of injection to work<div><p>Yes,</p>
<p>that is another option.</p>
<p>You just want the injector to create it.</p></div>matejtag:robotlegs.tenderapp.com,2009-10-18:Comment/300390332013-11-18T13:39:10Z2013-11-18T13:39:10ZThe necessary conditions of injection to work<div><p>It this case why when I inject, then the injected value is
null?</p></div>naghekyantag:robotlegs.tenderapp.com,2009-10-18:Comment/300390332013-11-18T14:40:28Z2013-11-18T14:40:28ZThe necessary conditions of injection to work<div><p>Lets start from zero :)</p>
<p>to use [Inject] in any class, that class has to be created with
injector.</p>
<p>there are multiple ways to create the class with injector, but
plain new Class() will not work.</p>
<ol>
<li>you can create the class most directly with
injector.instantiateUnmapped.<br></li>
<li>You can map the class with injector.map(Class) in your config,
and then inject the class into some other class, command model
ext…</li>
</ol>
<p>[Inject] public var classWithInjections:Class();</p>
<p>Where does it come null to you?</p></div>matejtag:robotlegs.tenderapp.com,2009-10-18:Comment/300390332013-11-18T17:16:31Z2013-11-18T17:16:31ZThe necessary conditions of injection to work<div><p>I wrote down a pretty long explanation, but then I had to do
something else and couldn't continue. Even though Matey has already
answered your questions, I'll post my unfinished answer too, just
to confuse you some more :P</p>
<blockquote>
<p>It this case why when I inject, then the injected value is
null?</p>
</blockquote>
<p>There could be lots of causes for that. Without more info it is
impossible to know what's going on in your app.</p>
<p>Some of the common causes are here : <a href=
"https://github.com/robotlegs/robotlegs-framework/wiki/Common-Problems">
https://github.com/robotlegs/robotlegs-framework/wiki/Common-Problems</a></p>
<p>Where are you trying to inject IMyClass? Does the class that
needs IMyClass have a mapping, i.e. does the Injector know about
it?</p>
<p>Let's say you want to inject ClassC into ClassB, and ClassB into
ClassA.</p>
<p>You need a mapping for all of them, and as Matej already told
you, the injector has to be the one who instantiates them, in a way
or another.</p>
<pre>
<code>injector.map(ClassA).asSingleton();
injector.map(ClassB).asSingleton();
injector.map(ClassC).asSingleton();</code>
</pre>
<p>Now, the Injector has rules for the 3 classes. But, <strong>the
mapping alone isn't enough to make the injection happen</strong>.
The Injector needs an injection point:</p>
<p>** ClassA **</p>
<pre>
<code>[Inject]
public var classB:ClassB;</code>
</pre>
<p>First now it will instantiate ClassB. <strong>The Injector
instantiates classes only on request</strong>. The injection point,
in the above case, represents the request. It says, dear Injector,
I really need ClassB to be injected in here. The Injector looks for
an existing mapping for ClassB, and if it finds one, it provides
the needy class with an instance of ClassB (same or new, depending
on the mapping). So, both, ClassA and ClassB must have a
mapping.</p>
<p>Variant 1a + error:</p>
<pre>
<code>injector.map(ClassA).asSingleton();
var classB:ClassB = injector.getOrCreateNewInstance(ClassB);
//or
//var classB:ClassB = injector. instantiateUnmapped (ClassB);
injector.map(ClassB).toValue(classB);
injector.map(ClassC).asSingleton();</code>
</pre>
<p>You'd get an error for a missing rule for ClassC, because ClassB
has been instantiated before its dependency (ClassC) could be
provided.<br>
The [Inject] public var classC:ClassC; inside ClassB is a request
to instantiate ClassC, but without a mapping the Injector will
reject the request (Injector is missing a mapping to handle
injection into property....)</p>
<p>So, you'd have to change the order of the mappings.</p>
<p>Variant 1b + no error:</p>
<pre>
<code>injector.map(ClassA).asSingleton();//1
injector.map(ClassC).asSingleton();//2
var classB:ClassB = injector.getOrCreateNewInstance(ClassB);//3
injector.map(ClassB).toValue(classB);</code>
</pre>
<p>Variant 2a + error:</p>
<pre>
<code>injector.map(ClassA).asSingleton();
var classB:ClassB = new ClassB();
injector.map(ClassB).toValue(classB);
injector.map(ClassC).asSingleton();</code>
</pre>
<p>Here, the injection of ClassB into ClassA will work, but ClassC
won't be injected into ClassC. ClassB has a mapping, but the
Injector can't fulfil the request for ClassC.</p>
<p>Variant 2b + no error:</p>
<pre>
<code>injector.map(ClassA).asSingleton();
injector.map(ClassC).asSingleton();
var classB:ClassB = new ClassB();
injector.map(ClassB).toValue(classB);
injector.injectInto(classB);//the object, not the Class!</code>
</pre>
<p><strong>injectInto()</strong> Inspects the given object and
injects into all injection points configured for its class. The
Injector must have mappings for all injection points.</p>
<p>Look at the comments inside Injector and InjectionMapping:<br>
<a href=
"https://github.com/robotlegs/swiftsuspenders/blob/master/src/org/swiftsuspenders/Injector.as">
https://github.com/robotlegs/swiftsuspenders/blob/master/src/org/sw...</a></p>
<p><a href=
"https://github.com/robotlegs/swiftsuspenders/blob/master/src/org/swiftsuspenders/mapping/InjectionMapping.as">
https://github.com/robotlegs/swiftsuspenders/blob/master/src/org/sw...</a></p>
<p>Here the 3 Classes. You can play around with different mappings.
Somewhere, where you inject ClassA, put a trace for
classA.aProperty.</p>
<pre>
<code> public class ClassA
{
[Inject]
public var classB:ClassB;
private var _aProperty:String = "aaa";
public function ClassA()
{
trace("ClassA.ClassA()");
}
public function get aProperty():String
{
return _aProperty + " " + classB.bProperty;
}
public function set aProperty(value:String):void
{
_aProperty = value;
}
}
public class ClassB
{
[Inject]
public var classC:ClassC;
private var _bProperty:String = "bbb";
public function ClassB()
{
trace("ClassB.ClassB()");
//BAD: classC is not available in the constructor
//trace("ClassB.ClassB() "+classC.cProperty);
}
public function get bProperty():String
{
trace("ClassB.bProperty()");
return _bProperty + " " + classC.cProperty;
}
public function set bProperty(value:String):void
{
_bProperty = value;
}
}
public class ClassC
{
private var _cProperty:String = "ccc";
public function ClassC()
{
trace("ClassC.ClassC()");
}
public function get cProperty():String
{
return _cProperty;
}
public function set cProperty(value:String):void
{
_cProperty = value;
}
}</code>
</pre></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/300390332013-11-19T10:29:22Z2013-11-19T10:29:22ZThe necessary conditions of injection to work<div><p>@matej, @Ondina guys! I am so impressed with great the help you
provide. This was so complete and descriptive. Thank you for your
time and effort guys!</p></div>naghekyantag:robotlegs.tenderapp.com,2009-10-18:Comment/300390332013-11-19T11:15:32Z2013-11-19T14:39:01ZThe necessary conditions of injection to work<div><p>Thanks for the kind words! We, guys and girls, men and women, in
the robotlegs community are glad to be of help ;)</p>
<p>May I mark this discussion as resolved?</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/300390332013-11-19T15:28:20Z2013-11-19T15:28:20ZThe necessary conditions of injection to work<div><p>Sure! :)</p></div>naghekyan