tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/9135-implementing-on-interfacesRobotlegs: Discussion 2014-08-28T08:59:50Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/340938542014-08-11T12:05:57Z2014-08-11T12:05:57Zimplementing on interfaces<div><p>Hello,</p>
<p>I have a problem with implementing on interfaces.<br>
I am trying to rearrange my application based in interfaces for
services.</p>
<p>For one service now I have two different implementations. Before
it was just one.<br>
Before it was like this:</p>
<p>injector.mapSingletonOf(ArduinoConnect);</p>
<p>and then I injected ArduinoConnect to some commands for sending
data to a TCP socket.<br>
Now there is a second implementation for UDP.<br>
To chaange thoe code as fast as possible to change between those
classes I created an interface calling IArduinoConnect.<br>
Both classes implements it.</p>
<p>The commands now injecting IArduinoConnect instead of
ArduinoConnect.<br>
The Context now defines injector.mapSingletonOf(IArduinoConnect,
ArduinoConnectUDP);<br>
or in case of TCP injector.mapSingletonOf(IArduinoConnect,
ArduinoConnectTCP);<br>
So I dont have to change it in every command.</p>
<p>Is that right?</p>
<p>Now I always get a trace:<br>
Warning: Injector already has a rule for type
"flash.events::Event", named "".<br>
If you have overwritten this mapping intentionally you can use
"injector.unmap()" prior to your replacement mapping in order to
avoid seeing this message.</p>
<p>What does that mean?</p></div>iamabletag:robotlegs.tenderapp.com,2009-10-18:Comment/340938542014-08-11T14:00:25Z2014-08-11T14:00:25Zimplementing on interfaces<div><p>I'm glad that you've decided to use interfaces:)</p>
<blockquote>
<p>The commands now injecting IArduinoConnect instead of
ArduinoConnect. The Context now defines
injector.mapSingletonOf(IArduinoConnect, ArduinoConnectUDP);<br>
or in case of TCP injector.mapSingletonOf(IArduinoConnect,
ArduinoConnectTCP);<br>
So I dont have to change it in every command. Is that right?</p>
</blockquote>
<p>Almost right. I'll try to explain why the mappings for your
service classes don't work as expected.<br>
Actually, you should have gotten a warning about your
IArduinoConnect instead of flash.events::Event. I don't know what
other mappings you have in your context, that caused that
warning.<br>
Anyway, back to your mappings:</p>
<pre>
<code>injector.mapSingletonOf(IArduinoConnect, ArduinoConnectUDP);
injector.mapSingletonOf(IArduinoConnect, ArduinoConnectTCP);</code>
</pre>
<pre>
<code>mapSingletonOf(whenAskedFor:Class, useSingletonOf:Class, named:String=""):</code>
</pre>
<p><strong>mapSingletonOf</strong> = When asked for an instance of
the class whenAskedFor inject an instance of useSingletonOf. This
will create an instance on the first injection, but will re-use
that instance for subsequent injections</p>
<p>When you inject IArduinoConnect somewhere, the Injector will use
an instance of the class passed as the second parameter to
mapSingletonOf.<br>
The first mapping tells the Injector: whenAskedFor IArduinoConnect,
inject an instance of ArduinoConnectUDP.<br>
Then, the second mapping tells the Injector: whenAskedFor
IArduinoConnect, inject an instance of ArduinoConnectTCP. Hmm, what
now? Which of the 2 classes should be injected? The Injector is
totally confused ;)</p>
<p>The second mapping will override the first one, thus wherever
you inject IArduinoConnect, you'll get ArduinoConnectTCP. Since the
injector can't distinguish between the 2 mappings, first it warns
you about it, and then it uses the second rule to fulfil
injections.</p>
<p>When you map the same interface to multiple classes in the same
context, you need to use <strong>named injections</strong> (see
third parameter in the mapSingletonOf):</p>
<pre>
<code>injector.mapSingletonOf(IArduinoConnect, ArduinoConnectUDP, "udp");
injector.mapSingletonOf(IArduinoConnect, ArduinoConnectTCP, "tcp");</code>
</pre>
<p>Now, there are 2 distinct rules, and the Injector is very happy
and ready to supply the correct dependencies to the classes needing
them, if you also define the injection points like this:</p>
<pre>
<code>[Inject (name="udp")]
public var udpService: IArduinoConnect;//= = ArduinoConnectUDP instance</code>
</pre>
<pre>
<code>[Inject (name="tcp")]
public var tcpService: IArduinoConnect;//= = ArduinoConnectTCP instance</code>
</pre>
<p>More on how injection works (it refers to rl2, but the principle
are the same):<br>
<a href=
"http://knowledge.robotlegs.org/discussions/robotlegs-2/5766-automagic-view-injection#comment_28759520">
http://knowledge.robotlegs.org/discussions/robotlegs-2/5766-automag...</a></p>
<p>Let me know if you need more explanations, in case this one
wasn't clear enough to you.<br>
Also, try to find out which mapping is causing the warning about
flash.events::Event, and post the code for that mapping, so I can
tell you what's going wrong.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/340938542014-08-12T13:36:21Z2014-08-12T13:36:21Zimplementing on interfaces<div><p>Thanks for your detailed reply!</p>
<p>Hahaha yes I try to use interfaces because my application is
going to have several variants.<br>
I understand what you meant but this isn't what I meant ;-)</p>
<p>I don't want to use both classes within that application. I just
have two variants.<br>
I will build one application with UDP and another with TCP.<br>
So within thjat application I am using always just one of that
classes and I only have one of the singleton mappings. This
interface is only for injecting always the interface and just
changing the mapping for changing the class.</p>
<p>But if I understand right my way was correct?</p></div>iamabletag:robotlegs.tenderapp.com,2009-10-18:Comment/340938542014-08-12T15:11:54Z2014-08-12T15:11:54Zimplementing on interfaces<div><p>You're welcome!</p>
<blockquote>
<p>For one service now I have two different implementations. Before
it was just one.</p>
</blockquote>
<p>I thought you were referring to 2 implementations of a Service
class inside of the same application or context. That's why I gave
you the solution to such a situation.</p>
<p>But, that's right, if you have 2 different applications, or 2 or
more contexts within one application, you can use the interfaces
exactly as you did.</p>
<p>Can we consider this issue as being resolved?</p></div>Ondina D.F.