Update injections in a mediator from a command

simon's Avatar

simon

14 Jul, 2011 01:42 AM

Hi,

I'm trying to create a command that will swap two service class mappings that are being used in a mediator.

I have in my context:

injector.mapSingletonOf(ISearchService, OtherSearchService);

And in my command i do:

injector.unmap(ISearchService);
injector.mapSingletonOf(ISearchService, TwitterSearchService);

While this doesn't throw any errors, it seems to have no effect. I then thought i would try doing something like:

[Inject]
public var theMediator : TheMediator
...
injector.injectInto(theMediator)

This throws an error telling me theres a rule missing for TheMediator to be injected. I tried to injector.mapSingleton(TheMediator) in my context, but that wasn't any good. I also read that accessing mediators from commands is something that is intentionally difficult and is discouraged.

So the question is whether there is some way of updating the injections in TheMediator or if there's another way to change the mapping of the services.

Many thanks in advance and thanks for this great project :-)
Simon

  1. 1 Posted by Stray on 14 Jul, 2011 07:52 AM

    Stray's Avatar

    Hi Simon,

    you shouldn't re-inject an object at runtime. We don't support that work flow at all.

    This is one of the reasons that we don't advise injecting other things into Mediators - just their view.

    In the next version (1.6) of Robotlegs (out within the next week or so) you can't inject Mediators into other objects at all - it was something that was an accidental by product of how the mediator mappings were carried out.

    You should fire an event from your mediator which you pick up in the Command and send to the service. And your service should fire an event (or a model should, after update by the service) which the mediator picks up to give the result to the view.

    So - unfortunately the answer is "Don't inject services into your Mediator". Timing issues like these are part of the reason why we advise against it.

    The alternative is that you use a Service locator ... which is a very un-Robotlegs way to do things, but would work.

    If you're absolutely sold on not changing things, then the following code in your command would achieve what you want...

    [Inject]
    public var theMediator:TheMediator;

    override public function execute():void
    {
    injector.unmap(ISearchService);
    injector.mapSingletonOf(ISearchService, TwitterSearchService);

    var serviceInstance:ISearchService = injector.getInstance(ISearchService);

    theMediator.searchService = serviceInstance;
    }

    However - this will mean you can't update to the next version of Robotlegs when it comes out.

    But you should really just try out the events approach - it's very, very reliable.

    I'm sorry if that's not what you wanted to hear!

    Stray

  2. 2 Posted by simon on 14 Jul, 2011 04:57 PM

    simon's Avatar

    Thanks for your reply!

    That's just what I wanted to hear! :-) I did feel that it wasn't very clean to inject the mediator, I just couldn't come up with anything that seemed more logical.

    However, I'm not quite sure I understand your solution. What I intended was simply to swap the TwitterSearchService and OtherSearchService in the mapping of ISearchService, because I thought it better than doing some sort of conditional (in the mediator that requests data) against a model; something like:

    if (someModel.service == "twitter")
        twitterSearch.getResults()
    else if (someModel.service == "other")
        otherSearch.getResults()
    

    I'm not sure I'm explaining myself right here, but I hope you get the idea.

    Is the unmapping and remapping of a new class not the way at all? To me it seems incredibly simple and clean, and the "only" thing missing is the updating of the mediator.

  3. 3 Posted by Stray on 14 Jul, 2011 05:08 PM

    Stray's Avatar

    Hi Simon,

    what you could do is send an event from your mediator rather than try to use the service directly.

    That way you can still map / unmap your service, but because the command is created only when the event fires, it will always use the correct version of the service.

    so - I'd avoid putting the service direct into your mediator, then your problem goes away.

    Stray

  4. 4 Posted by simon on 14 Jul, 2011 05:44 PM

    simon's Avatar

    Ah! That sounds good! Thanks a lot! :-)

  5. simon closed this discussion on 14 Jul, 2011 05:44 PM.

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