ASP.NET Core Repository 適合的生命週期

April 14, 2024

在 ASP.NET Core 內,依賴注入服務時,會需要指定該類別的生命週期。那麼存取外部資源的 Repository Class,適合哪種生命類別。 本文僅為網路和個人看法,沒有標準答案。

看法

關於生命週期的描述,請先參考 [.Net Core] 服務存留期 (Service Lifetime):叡揚部落格 與拙作 ASP.NET Core 的服務生命週期、註冊與使用 – Lazy Coding

使用 Singleton 的理由為:不需要每次有新的請求時,都重新注入、初始化。

使用 Scoped 的理由為:非同步的情形下,Repository 類別可能是不安全的,應該根據各請求的狀態分別產生 Repository 物件使用。

個人因為使用的類別為無狀態,而且會將資料存入快取,因此使用 Singleton 生命週期注入。

在 Singleton 類別內建立 Scoped 類別物件的作法

假設今天有 SingletonService 類別,已被註冊為 Singleton。若要在其中建立已經被註冊為 Scoped、實作 IScopedDbContext 介面的類別,可以參考以下程式碼:

public class SingletonService : ISingletonService 
{
    private readonly IServiceProvider _serviceProvider;

    public SingletonService (IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public async Task DoSomething()
    {
        using (var scope = _serviceProvider.CreateScope())
        {
             var context = scope.ServiceProvider.GetRequiredService<IScopedDbContext>();
             // 實作內容
        }
    }
}

但這可能是不好的設計 (Singleton 類別內使用的物件應該都要有相同的生命週期),應盡量避免這樣做。

參考資料