【发布时间】:2019-04-16 12:44:56
【问题描述】:
在我的 Asp.Net Core 应用程序中,我需要一个可以在应用程序的生命周期内重复使用的单例服务。要构建它,我需要一个 DbContext(来自 EF Core),但它是一个作用域服务而不是线程安全的。
因此,我使用以下模式来构建我的单例服务。它看起来有点 hacky,因此我想知道这是否是一种可接受的方法并且不会导致任何问题?
services.AddScoped<IPersistedConfigurationDbContext, PersistedConfigurationDbContext>();
services.AddSingleton<IPersistedConfigurationService>(s =>
{
ConfigModel currentConfig;
using (var scope = s.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<IPersistedConfigurationDbContext>();
currentConfig = dbContext.retrieveConfig();
}
return new PersistedConfigurationService(currentConfig);
});
...
public class ConfigModel
{
string configParam { get; set; }
}
【问题讨论】:
-
有许多重复项展示了如何执行此操作。后台服务的文档也是如此。
PersistedConfigurationService的构造函数中应该有一个IServiceProvider参数。 它应该在需要时创建范围。 -
ServiceProvider只不过是一个“根”作用域;因此,您可以直接使用它(即无需创建范围)。 -
检查Consuming a scoped service in a background task。它表明
IServiceProvider被注入到单例服务的构造函数中。实际需要作用域服务的方法DoWork创建作用域并仅在实际需要时才请求服务。 -
@PanagiotisKanavos,感谢您分享带有示例的链接。我剩下的问题是我的方法是否很好,因为它正在做与你类似的事情,但在不同的地方(当服务的构建发生时,而不是在服务内部)
-
@TanvirArjel 是的,没错。很容易误解这一点,并认为我们有一个单例尝试使用范围服务,但我们没有。
标签: c# asp.net-core .net-core