How can I amend context at runtime?

borekb's Avatar


25 Jan, 2011 11:38 AM

I need to support runtime configuration of RL / dependency injection, how can I do that? Say that I've got logging service that logs to a remote service and with a hidden switch somewhere in the app, I need to change the logging target to a simple trace console as the app is running. Also note that I'll possibly need to switch between service implementations many times during the application run time.

  1. 1 Posted by Stray on 25 Jan, 2011 11:56 AM

    Stray's Avatar

    Two options:

    1) Wrap the service location in a model - ie

    public var loggingServiceLocator:ILoggingServiceLocator

    instead of injecting the service directly. And then pull the actual service from the service locator. Eg - in an UpdateLogCommand

    public override function execute():void
    var loggingService:ILoggingService = loggingServiceLocator.activeService;
    // then use it as normal

    2) Use dynamic mappings - probably via injector.mapValue

    // original mapping
    injector.mapValue(ILoggingService, RemoteLoggingService);


    // new mapping
    injector.mapValue(ILoggingService, TraceLoggingService);

    Personally I would go with 1, because it means that long-lived injections are supported. Approach 2 would only affect injections that occur after the mapping has been changed.

  2. 2 Posted by borekb on 25 Jan, 2011 12:22 PM

    borekb's Avatar

    Thanks. Will mapValue reinject the new instance to all existing commands, mediators etc.? (I not too keen on the service locator pattern.)

  3. 3 Posted by Stray on 25 Jan, 2011 12:39 PM

    Stray's Avatar

    That's exactly what I said at the bottom of my message...

    "Approach 2 would only affect injections that occur after the mapping has been changed."

    So - a Command, yes, because it's a new instance.

    You shouldn't be injecting services into mediators anyway, so if you've stuck to the purist approach - services and models only accessed through Commands - then yes, your new mapping will be honoured. If you've injected into mediators and they're on stage already, they'll still have the old mapping.

    If you have used mediator injection then you'll definitely need to use the service locator pattern. I don't know why you'd be 'unkeen' on that pattern though - models are for storing dynamic parts of the system. If this part is dynamic then why not model it? Seems sensible and much easier to understand and trace problems in code that uses this approach than dynamic mappings.

  4. 4 Posted by Paul Robertson on 25 Jan, 2011 04:06 PM

    Paul Robertson's Avatar

    Another approach I've used is this (it's conceptually similar to what
    Stray recommends, but implemented differently):

    - create an event that triggers the logging, i.e. LogEvent(message)

    - for each logging output, create a separate command that expects a
    LogEvent and calls a particular logging service, e.g. LogToFileCommand,
    LogToConsoleCommand, etc.

    - at startup, only map the default logging mechanism to the event:
    commandMap.mapEvent(LogEvent.LOG, LogToFileCommand...)

    - when you want to switch to a different logging mechanism, do that in
    another command, e.g.:
    override public function execute():void
         commandMap.unmapEvent(LogEvent.LOG, LogToFileCommand...)
         commandMap.mapEvent(LogEvent.LOG, LogToConsoleCommand...)

    Of course you don't necessarily have to unmap the one type; you could
    just add an additional logging mechanism, or do whatever you like for
    your app.

    And obviously I've left out lots of details like the events that trigger
    the enabling commands. Hopefully this is enough to communicate the idea.


  5. 5 Posted by borekb on 25 Jan, 2011 09:30 PM

    borekb's Avatar

    Thanks guys.

  6. Stray closed this discussion on 11 Feb, 2011 11:17 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts


? 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