我的情况很常见,但我找不到答案。我有集成测试,在每个设置中都会模拟一些服务。我必须更新 Autoufac 容器以获取这些模拟的构造函数注入。所以基本上我有所有应用程序注册的主容器,并且需要为每个测试场景的那些被覆盖的服务创建一些子容器/生命周期范围。我已经注册了自定义 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;
}
}
}
从静态构造函数调用
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); 持有所有初始注册
并有一些模拟创建逻辑,在每个测试设置上注册新模拟
builder.Register(c => mockInitializer.ServiceMock)
.As(mockInitializer.ServiceType)
.InstancePerMatchingLifetimeScope("TestLifeScope");
builder.Update(Container);
我也有关于 TearDown 的处理逻辑
[TearDown]
public virtual void TearDown()
{
LsProvider.EndTestLifetimeScope();
}
但事情是即使子范围在每次测试后被释放,所有注册都保留在主容器中。因此,当我运行不应模拟服务实现的测试时,并且在此接口上从以前的测试中注册了一些模拟,它就会被使用。
我无法在每个测试设置上构建容器,因为我的父类为测试恢复创建了事务,所以我需要在静态构造函数中构建容器,该构造函数首先运行以解决所有 IRepository 接口等。
我也尝试过 BeginLifetimeScope(c => ...) 技术但也没有成功
有人有什么想法吗?谢谢
ps 我使用 Autofac 3.0.1 版本和 MVC 4