implementing on interfaces

iamable's Avatar

iamable

11 Aug, 2014 12:05 PM

Hello,

I have a problem with implementing on interfaces.
I am trying to rearrange my application based in interfaces for services.

For one service now I have two different implementations. Before it was just one.
Before it was like this:

injector.mapSingletonOf(ArduinoConnect);

and then I injected ArduinoConnect to some commands for sending data to a TCP socket.
Now there is a second implementation for UDP.
To chaange thoe code as fast as possible to change between those classes I created an interface calling IArduinoConnect.
Both classes implements it.

The commands now injecting IArduinoConnect instead of ArduinoConnect.
The Context now defines injector.mapSingletonOf(IArduinoConnect, ArduinoConnectUDP);
or in case of TCP injector.mapSingletonOf(IArduinoConnect, ArduinoConnectTCP);
So I dont have to change it in every command.

Is that right?

Now I always get a trace:
Warning: Injector already has a rule for type "flash.events::Event", named "".
If you have overwritten this mapping intentionally you can use "injector.unmap()" prior to your replacement mapping in order to avoid seeing this message.

What does that mean?

  1. Support Staff 1 Posted by Ondina D.F. on 11 Aug, 2014 02:00 PM

    Ondina D.F.'s Avatar

    I'm glad that you've decided to use interfaces:)

    The commands now injecting IArduinoConnect instead of ArduinoConnect. The Context now defines injector.mapSingletonOf(IArduinoConnect, ArduinoConnectUDP);
    or in case of TCP injector.mapSingletonOf(IArduinoConnect, ArduinoConnectTCP);
    So I dont have to change it in every command. Is that right?

    Almost right. I'll try to explain why the mappings for your service classes don't work as expected.
    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.
    Anyway, back to your mappings:

    injector.mapSingletonOf(IArduinoConnect, ArduinoConnectUDP);
    injector.mapSingletonOf(IArduinoConnect, ArduinoConnectTCP);
    
    mapSingletonOf(whenAskedFor:Class, useSingletonOf:Class, named:String=""):
    

    mapSingletonOf = 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

    When you inject IArduinoConnect somewhere, the Injector will use an instance of the class passed as the second parameter to mapSingletonOf.
    The first mapping tells the Injector: whenAskedFor IArduinoConnect, inject an instance of ArduinoConnectUDP.
    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 ;)

    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.

    When you map the same interface to multiple classes in the same context, you need to use named injections (see third parameter in the mapSingletonOf):

    injector.mapSingletonOf(IArduinoConnect, ArduinoConnectUDP, "udp");
    injector.mapSingletonOf(IArduinoConnect, ArduinoConnectTCP, "tcp");
    

    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:

    [Inject (name="udp")]
    public var udpService: IArduinoConnect;//= = ArduinoConnectUDP instance
    
    [Inject (name="tcp")]
    public var tcpService: IArduinoConnect;//= = ArduinoConnectTCP instance
    

    More on how injection works (it refers to rl2, but the principle are the same):
    http://knowledge.robotlegs.org/discussions/robotlegs-2/5766-automag...

    Let me know if you need more explanations, in case this one wasn't clear enough to you.
    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.

  2. 2 Posted by iamable on 12 Aug, 2014 01:36 PM

    iamable's Avatar

    Thanks for your detailed reply!

    Hahaha yes I try to use interfaces because my application is going to have several variants.
    I understand what you meant but this isn't what I meant ;-)

    I don't want to use both classes within that application. I just have two variants.
    I will build one application with UDP and another with TCP.
    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.

    But if I understand right my way was correct?

  3. Support Staff 3 Posted by Ondina D.F. on 12 Aug, 2014 03:11 PM

    Ondina D.F.'s Avatar

    You're welcome!

    For one service now I have two different implementations. Before it was just one.

    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.

    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.

    Can we consider this issue as being resolved?

  4. Ondina D.F. closed this discussion on 28 Aug, 2014 08:59 AM.

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