我们在使用 Autofac 进行范围界定时遇到了一个基本问题。在我们的方案中,我们有一些单一实例范围的存储库。这些存储库注入了 IDbContextProvider(也是单例范围的)。IDbContextProvider 只是注入的 Autofac IComponentContext 的包装器。当需要 DbContext 时,存储库会从 DBContextProvider 请求它。DbContext的范围基本上是每个请求,因为这是一个Web API。
所以这个想法是存储库可以是单例范围的,因为它们没有那么多,DBContext 的范围由 Autofac 作为"每个请求"进行管理。这依赖于这样一个前提,即 Autofac ComponentContext 应该理解它当前所处的"叶"上下文并返回正确的 DbContext。一位提出这种策略的同事告诉我,这是StructurMap(显然是不同的产品)所表现出的行为。对我来说,Autofac将解析当前的"叶"上下文并返回正确的DbContext是有道理的,但是我们看到DbContext的并发问题,这使我得出结论,IComponentContext被固定到拥有它的单例,因此返回相同的DbContext实例。
//This is singleton scoped
public class DbContextProvider : IDbContextProvider
{
private readonly IComponentContext _componentContext;
public DbContextProvider(IComponentContext componentContext)
{
_componentContext = componentContext;
}
public TDbContext GetDbContext<TDbContext>() where TDbContext : IDbContext
{
//DbContext is scoped PerLifetimeScope but the component context
//appears to only understand the context of the singleton that owns
//it and returns the same instance no matter the overall context
//under which is is requested.
return _componentContext.Resolve<TDbContext>();
}
}
有没有办法完成我们在这里要做的事情,或者是唯一将整个依赖树范围限定为 PerLifetime Scope 以获得正确行为的操作过程。
谢谢。。。
IComponentContext
使用相关生存期解析,但相关生存期在这里是单例,因此它将在容器中解析。你应该使用DependencyResolver.Current.GetService
public class DbContextProvider : IDbContextProvider
{
public DbContextProvider()
{
}
public TDbContext GetDbContext<TDbContext>() where TDbContext : IDbContext
{
//DbContext is scoped PerLifetimeScope but the component context
//appears to only understand the context of the singleton that owns
//it and returns the same instance no matter the overall context
//under which is is requested.
return DependencyResolver.Current.GetService.Resolve<TDbContext>();
}
}
您也可以查看本文。