MurabitoB

.Net Core Dependency Injection Scoped 注入到 Singleton

N 人看过

環境

  • .Net Core 3.1

問題

踩雷.

在專案中如果想對 Singleton 的 Service 中直接注入 Scoped 的 Service 的話,會拋出 Exception

下面範例取自黑暗執行緒

System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: CRUDExample.Models.MemoryUsageMonitor': Cannot consume scoped service 'CRUDExample.Models.JournalDbContext' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.)'

原因是因為是在 Scoped 的生命週期結束後(一次 Request), Singleton 依然會存在,這並不符合設計的規範.

解法

如果要解決這問題,可以在 Singleton Service 定義一個 Scope,透過在 Singleton 的 service provider ,再透過該 service provider 來提供 Scope 的區間,明確定義出 Scope 的範圍,這樣就可以迴避掉 exception.

// 先注入 IServiceProvider 到你的 class
public YourClass(IServiceProvider serviceProvider)
{
    _serviceProvider = serviceProvider;
}

// 生成 Scope
using(var s = _serviceProvider.CreateScope())
{
    s.ServiceProvider.GetService<ICustomService>();
}

參考資料:

https://stackoverflow.com/questions/55708488/using-a-scoped-service-in-a-singleton-in-an-asp-net-core-app

https://blog.darkthread.net/blog/aspnetcore-use-scoped-in-singleton/