Simple Injector dynamic context-based injection at runtime between two registrations

前端 未结 1 551
隐瞒了意图╮
隐瞒了意图╮ 2021-01-28 16:22

I have a Mediator application using Simple Injector for command handler registration, and injection and handlers is all setup and working perfectly.

class DoWash         


        
相关标签:
1条回答
  • 2021-01-28 17:09

    I'm not sure I fully understand your use case, and what it is that leads to this, but what you can do is create a wrapper IBus implementation that forwards the call to the correct bus, while changing the forwarded bus implementation while running on a background thread.

    This wrapper might look as follows:

    class SwitchableBus : IBus
    {
        private readonly DispatchInCallingThread defaultBus;
        private readonly DispatchOnBackgroundThread backgroundBus;
    
        public SwitchableBus(
            DispatchInCallingThread defaultBus, DispatchOnBackgroundThread backgroundBus)
        {
            this.defaultBus = defaultBus;
            this.backgroundBus = backgroundBus;
            this.Bus = defaultBus;
        }
    
        public IBus Bus { get; private set; }
    
        public void SwitchToBackgroundBus() => this.Bus = this.backgroundBus;
    
        public Task<object> Send(object command) => this.Bus.Send(command);
    }
    

    With this wrapper, you can use the following registrations:

    container.Register<IBus, SwitchableBus>(Lifestyle.Scoped);
    container.Register<SwitchableBus>(Lifestyle.Scoped);
    container.Register<DispatchInCallingThread>(Lifestyle.Scoped);
    container.Register<DispatchOnBackgroundThread>(Lifestyle.Scoped);
    

    This allows you to have DispatchInCallingThread used in the graph as follows:

    using(SomeSope.BeingScope(container))
    {
        var handler = this.container.GetInstance(requestHandlerType);
        handler.Handle(request);
    }
    

    In other words, by default the DispatchInCallingThread is used.

    And DispatchOnBackgroundThread can be used by the graph as follows:

    using(SomeSope.BeingScope(container))
    {
        container.GetInstance<SwitchableBus>().SwitchToBackgroundBus();
    
        var handler = this.container.GetInstance(requestHandlerType);
        handler.Handle(request);
    }
    

    Concequence of this is, however, that you should always resolve within an active Scope. But that would be a good idea anyway, because it is likely there will be Scoped dependencies in a graph anyway. Simple Injector does not allow resolving a graph with Scoped dependencies outside the context of an active scope.

    0 讨论(0)
提交回复
热议问题