请问以下代码行有什么问题:-
为什么我不能在上面使用单例?
services.AddSingleton<IProductRepository, ProductRepository>();
我在上面的代码中收到500个内部服务器错误,但是与Transient
和Scoped
一起正常工作。
答案 0 :(得分:3)
我根据提供的模式假设存储库依赖于DbContext
?
public class ProductRepository : IProductRepository {
public ProductRepository (MyDbContext db) {
//...
}
}
倾向于注册为作用域。
如果您尝试注册具有作用域依赖性的单例,则在处理后续请求时可能导致服务处于错误状态。
答案 1 :(得分:1)
从单例中解析作用域服务很危险。处理后续请求时,可能导致服务的状态不正确。
现在看看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>