前言

依賴注入(Dependency Injection, DI) 是一種實現控制反轉(Inversion of Control, IoC) 的軟件設計模式,也是構建鬆耦合、可測試、易維護應用程序的核心技術。其核心理念是:不要在類內部創建依賴,而是由外部容器將依賴注入進來。

在現代 ASP.NET Core 中內置了強大的 DI 容器,正確使用 DI 的關鍵在於理解 Transient、Scoped 和 Singleton 這三種服務生命週期,它們決定了服務實例的創建時機、共享範圍與生命週期。本文將清晰解析三者的區別和適用場景。

簡單概述

在 ASP.NET Core 中,依賴注入容器通過IServiceCollection支持三種服務註冊生命週期:

IServiceCollection 是 .NET 依賴注入(DI)系統中的核心接口之一,用於註冊和管理應用程序所需的服務。

生命週期

註冊方法

實例創建時機

共享範圍

Transient(瞬態)

AddTransient<T>()

每次請求都創建新實例

不共享

Scoped(作用域)

AddScoped<T>()

每個作用域(如 HTTP 請求)創建一次

在同一作用域內共享

Singleton(單例)

AddSingleton<T>()

應用啓動時創建一次(或首次使用時)

整個應用生命週期共享

選型口訣

  • 跨請求共享、需複用 → Singleton(線程安全要做好)
  • 請求內共享、一致性、上下文傳遞 → Scoped
  • 一次性、無狀態、輕量 → Transient

Transient(瞬態)

每次從 DI 容器請求服務時,都會創建一個全新的實例

適用場景

  • 輕量級、無狀態的服務。
  • 請求級獨立狀態:每次調用需要獨立狀態或副作用隔離的組件。
  • 短生命週期依賴鏈:依賴鏈中各服務都很輕、無共享資源的場景。

Scoped(作用域)

同一個作用域內共享同一個實例,不同作用域創建不同實例。

在 ASP.NET Core 中,每個 HTTP 請求就是一個作用域

適用場景

  • 需要在單次請求中共享狀態的服務。
  • 數據庫上下文(DbContext):AddDbContext() 默認註冊為 Scoped,保證同一 HTTP 請求內複用同一個數據庫上下文,避免實體跟蹤混亂、重複連接開銷,並支持事務一致性。
  • 工作單元(Unit of Work)與數據倉儲(Repository):與 DbContext 同生命週期,保障查詢→修改→提交的一致性,並減少資源創建銷燬。

Singleton(單例)

整個應用程序生命週期內只創建一次實例,所有請求共享同一個對象。

適用場景

  • 無狀態、線程安全的全局服務(如工具類、映射器)。
  • 配置封裝服務(如 IAppSettings),啓動後內容不變。
  • 全局緩存(如 IMemoryCache),需跨請求共享數據。

參考文章

  • https://learn.microsoft.com/zh-cn/dotnet/core/extensions/dependency-injection#service-lifetimes