How to change the registration of dependencies at runtime using a simple injector?

I am using the Simple Injector IoC framework and I would like to be able to change the registration of dependencies at runtime. For example, I have two implementations, Aand B, an interface I. The implementation is Aregistered at the beginning of the application, but depending on some flag that may change at runtime, I would like to switch the implementation. We are currently making this OnActionExecutingour event BaseControllerfrom which all our controllers are inherited. Here is a sample code of what I'm trying to do.

protected override void OnActionExecuting(
    ActionExecutingContext filterContext)
{
    if (IsRuntimeFlag)
    {
        // check current implementation type and 
        // change implementation to A
    }
    else
    {
        // check current implementation type and 
        // change implementation to B
    }

    base.OnActionExecuting(filterContext);
}

Thanks in advance for your help.

+5
source share
1

, IsRuntimeFlag ( , ), :

if (IsRuntimeFlag)
{
    container.Register<I, A>();
}
else
{
    container.Register<I, B>();
}

:

container.Register(typeof(I), IsRuntimeFlag ? typeof(A) : typeof(B));

, , composite, ​​ , :

public sealed class RuntimeFlagIComposite : I
{
    private readonly A a;
    private readonly B b;

    public RuntimeFlagIComposite(A a, B b) {
        this.a = a;
        this.b = b;
    }

    void I.Method() => this.Instance.Method();

    private I Instance => IsRuntimeFlag ? this.a : this.b;
}

A B, :

container.Register<I, RuntimeFlagIComposite>();

A B , ( ), . :

container.Register<A>(Lifestyle.Singleton);
container.Register<B>(Lifestyle.Scoped);

I A B:

public class RuntimeFlagIComposite : I
{
    private I a;
    private I b;

    public RuntimeFlagIComposite(I a, I b)
    {
        this.a = a;
        this.b = b;
    }
}

I . , , :

container.Register<I, RuntimeFlagIComposite>();

container.RegisterConditional<I, A>(c => c.Consumer.Target.Name == "a");
container.RegisterConditional<I, B>(c => c.Consumer.Target.Name == "b");
+9

All Articles