依赖注入ASP.NET Core Singleton

时间:2018-12-26 11:34:10

标签: c# asp.net-core dependency-injection

请问以下代码行有什么问题:-

为什么我不能在上面使用单例?

services.AddSingleton<IProductRepository, ProductRepository>();

我在上面的代码中收到500个内部服务器错误,但是与TransientScoped一起正常工作。

2 个答案:

答案 0 :(得分:3)

我根据提供的模式假设存储库依赖于DbContext

public class ProductRepository : IProductRepository {

    public ProductRepository (MyDbContext db) {
        //...
    }
}

倾向于注册为作用域。

如果您尝试注册具有作用域依赖性的单例,则在处理后续请求时可能导致服务处于错误状态。

引用Dependency injection in ASP.NET Core : Service Lifetimes

答案 1 :(得分:1)

根据Microsoft Documentiaon

  

从单例中解析作用域服务很危险。处理后续请求时,可能导致服务的状态不正确。

现在看看ConfigureServices类中的Startup方法的以下代码:

services.AddDbContext<ApplicationDbContext>(options =>
                       options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

UseSqlServer方法中,有一个用于 Service Lifetime 的第二个参数,其默认值为 ServiceLifetime.Scoped。可能是因为您没有指定第二个参数,所以它采用的是默认值ServiceLifetime.Scoped。这意味着您的DbContext已注册为Scoped service。现在,如果您在DbContext中使用ProductRepository,那么您的ProductRepository也必须被拒绝为Scoped Service,否则ASP.NET Core DI提供程序将无法解决它。

现在,如果您真的想将ProductRepository注册为Singleton服务,则使DbContext还要Singleton如下:

services.AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")),ServiceLifetime.Singleton);

现在应该可以了!

注意:我假设您的ProductRepository依赖于DbContext。如果不是,那么您的ProductRepository存储库必须依赖于注册为Scoped服务的服务,这就是为什么您当前无法将ProductRepository用作Singleton的原因。 / p>