[英]C# Dependency Injection Cannot Consume Scoped?
我沒有使用依賴注入的豐富經驗,但是我正在嘗試在我的一個項目中使用它。 當我嘗試向我的構造函數中添加第二個參數時,出現錯誤“無法從單例中使用作用域服務'CarbonService'...”。不確定為什么會收到此錯誤或丟失了什么。 謝謝你的幫助
我希望我的計時器類可以訪問CarbonService對象。
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDbContext<CarbonDBContext>(o => o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddHostedService<ValidUntilTimerService>();
services.AddScoped<ICarbonService, CarbonService>(); // I HAVE TRIED USING SINGLETON BUT SAME ERROR
services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));
}
ValidUntilTimerService.cs:
// ADDING THE SECOND PARAMETER TO THIS CONSTRUCTOR CAUSES THE ERROR.
public class ValidUntilTimerService : IHostedService, IDisposable
{
private readonly ILogger _logger;
private Timer _timer;
private ICarbonService _carbonService;
public ValidUntilTimerService(ILogger<ValidUntilTimerService> logger, ICarbonService carbonService)
{
_logger = logger;
_carbonService = carbonService;
}
...
}
CarbonService.cs:
public interface ICarbonService
{
WattTime ReadCarbon();
void SaveCarbon(int carbonIndex);
}
public class CarbonService : ICarbonService
{
private IConfiguration _configuration;
private readonly CarbonDBContext _dbcontext;
public CarbonService(IConfiguration configuration, CarbonDBContext dbContext)
{
_configuration = configuration;
_dbcontext = dbContext;
}
public WattTime ReadCarbon()
{
var wt = new WattTime();
...
return wt;
}
public void SaveCarbon(int carbonIndex)
{
...
}
}
IHostedService
被注冊為單例。 您將ICarbonService
注入ValidUntilTimerService
,這意味着您將范圍服務注入了單例服務。
如果我們考慮這兩種服務的壽命:
每個請求一次創建范圍服務。 這意味着,在實例化作用域服務時,該服務將保持活動狀態直到請求結束。
當實例化Singleton服務時,它將保持活動狀態,直到應用程序關閉。
我們意識到,從單例服務中使用范圍服務並沒有多大意義。 在這種情況下將發生以下情況:
實例化單例服務(在您的情況下為ValidUntilTimerService
)時,其作用域依賴項(在您的情況下為ICarbonService
)也被實例化並注入到單例服務中。 請求完成后,單例服務保持活動狀態,但作用域服務被處置。 現在,您的單例服務最終以“ _carbonService
”依賴關系(在您的情況下為_carbonService
字段)。
以上情況是不可能的。 這只是一個“假設”場景。 關鍵是, 您不能使用根據請求創建的服務,而無需請求即可創建的服務 (例如,在應用啟動時)。
現在,這說明了問題的原因,但讓我們看看您可以采取什么措施解決問題。
可能的解決方案
您可以使用IServiceScopeFactory在ValidUntilTimerService
內部創建自己的范圍:
public class ValidUntilTimerService : IHostedService, IDisposable
{
private readonly ILogger _logger;
private Timer _timer;
private IServiceScopeFactory _serviceScopeFactory;
public ValidUntilTimerService(ILogger<ValidUntilTimerService> logger, IServiceScopeFactory serviceScopeFactory)
{
_logger = logger;
_serviceScopeFactory = serviceScopeFactory;
}
// ...
using (var scope = _serviceScopeFactory.CreateScope())
{
ICarbonService carbonService = scope.ServiceProvider.GetService(typeof(ICarbonService));
// ...
}
// ...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.