Search code examples
c#simple-injector

Simple Injector: Replace registered type at runtime


Is there any way in Simple Injector to replace the default of one type at runtime as containter.Inject() in Structure Map? I borrow the code using Structure Map as follows

var container = new Container(x => { x.For<IFoo>().Use<AFoo>(); });
container.GetInstance<IFoo>().ShouldBeOfType<AFoo>();
container.Configure(x => x.For<IFoo>().Use<BFoo>());

// The default of IFoo is now different
container.GetInstance<IFoo>().ShouldBeOfType<BFoo>();

// or use the Inject method that's just syntactical
// sugar for replacing the default of one type at a time
container.Inject<IFoo>(new CFoo());

container.GetInstance<IFoo>().ShouldBeOfType<CFoo>();

My context

Register container

// bypass verify was removed for short
_container.Register<HttpContextBase>(() => new HttpContextWrapper(HttpContext.Current)); 
_container.Register(() => _container.GetInstance<HttpContextBase>().User.Identity);

My service

public class MyService : IMyService
{
    public MyService(IIdentity identity)
    {
        //...
    }
    //...
}

There is no problem with my app. It worked. But in my unit tests (real local DB without mock), I want to replace IIdentity with logged in user. I used Structure Map and it worked. Now I do not how to make it works with Simple Injector.


Solution

  • But in my unit tests (real local DB without mock), I want to replace IIdentity with logged in user.

    You can absolutely replace the real IIdentity registration with a different one for unit testing. You simply have to do this before resolving from the container.

    This means that every integration test (I say 'integration', since a unit test should not use a DI Container) should get its own Container instance. Secondly, to be able to override existing registrations, you will have to set container.Options.AllowOverridingRegistrations. For more information, read this.