Singleton Scoped对象从ComponentContext解析时的Autofac Scoping

时间:2016-04-23 14:11:22

标签: asp.net autofac

我们在使用Autofac进行范围界定时遇到了一个基本问题。在我们的场景中,我们有一些单例作用域的存储库。这些存储库注入了一个IDbContextProvider(也是单例作用域)。 IDbContextProvider只是注入的Autofac IComponentContext的包装器。当需要DbContext时,存储库会从DBContextProvider请求它。 DbContext的范围是" lifetimescope",基本上是每个请求,因为这是一个Web Api。

因此,我们的想法是存储库可以是单例作用域,因为它们中的许多存储区和DBContext的范围由Autofac管理为"每个请求"。这依赖于Autofac ComponentContext应该理解" leaf"它当前所在的上下文并返回正确的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>();
    }

}

有没有办法完成我们在这里所要做的事情,或者是将整个依赖关系树作为PerLifetimeScope来确定正确行为的唯一行动方案。

...谢谢

1 个答案:

答案 0 :(得分:0)

IComponentContext resolve with related lifetime but related lifetime is singleton here, so it will be resolved in container. You should use 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>();
    }

}

You can check this article also.