My case is quite common but i cannot find an answer. I have integration tests where on each setup some services are mocked. I have to update Autuofac container to get constructor injection of those mocks. So basically I have main container with all application registration and need to create some child container/lifetime scope for those overridden services for each test scenario. I have registered custom ILifetimeScopeProvider
public class TestLifetimeScopeProvider : ILifetimeScopeProvider
{
readonly ILifetimeScope container;
private ILifetimeScope lifetimeScope = null;
private ILifetimeScope testlifeScope = null;
public TestLifetimeScopeProvider(ILifetimeScope container)
{
if (container == null) throw new ArgumentNullException("container");
this.container = container;
}
public ILifetimeScope ApplicationContainer
{
get { return container; }
}
public ILifetimeScope GetLifetimeScope()
{
if (lifetimeScope == null)
{
lifetimeScope = ApplicationContainer.BeginLifetimeScope("AutofacWebRequest");
}
if (testlifeScope == null)
{
testlifeScope = lifetimeScope.BeginLifetimeScope("TestLifeScope");
}
return testlifeScope;
}
public ILifetimeScope GetLifetimeScope(Action<ContainerBuilder> configurationAction)
{
return GetLifetimeScope();
}
public void EndLifetimeScope()
{
if (lifetimeScope != null)
lifetimeScope.Dispose();
}
public void EndTestLifetimeScope()
{
if (lifetimeScope != null)
{
testlifeScope.Disposer.Dispose();
lifetimeScope = null;
}
}
}
which is invoked from static constructor
static TestBase()
{
var builder = new ContainerBuilder();
DependencyRegistrar.Register(builder);
Container = builder.Build();
LsProvider = new TestLifetimeScopeProvider(Container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(Container, LsProvider));
}
DependencyRegistrar.Register(builder); holds all initial registrations
and have some mock creation logic which registers new mock on each test setup
builder.Register(c => mockInitializer.ServiceMock)
.As(mockInitializer.ServiceType)
.InstancePerMatchingLifetimeScope("TestLifeScope");
builder.Update(Container);
also i have disposing logic on TearDown
[TearDown]
public virtual void TearDown()
{
LsProvider.EndTestLifetimeScope();
}
but thing is even if child scope gets disposed after each test all registrations stays in main container. So when i run tests where service implementation should not be mocked and there is some mock registered from previous tests on this interface it gets used.
I cannot build container on each test setup because my parent class creates transaction for test reverting so i need to build container in static constructor which runs first to solve all IRepository interfaces and etc.
I have also tried BeginLifetimeScope(c => ...) technique but also without success
Any thoughts someone? Thanks
p.s. i use Autofac 3.0.1 version and MVC 4