深入淺出 ASP.NET Core 依賴注入 (DI) 完整指南

Cover Image

1. 什麼是依賴注入 (Dependency Injection)?

在現代化的軟體開發中,依賴注入 (DI) 是一種非常重要的設計模式,它主要用於實現控制反轉 (IoC)。 簡單來說,就是「不要自己 new 物件,讓別人幫你 new 好送進來」。這樣可以大幅降低程式碼之間的耦合度 (Coupling), 讓系統更容易測試與維護。

"High cohesion, low coupling (高內聚,低耦合)" 是軟體架構設計的黃金準則。

2. 生命週期介紹

在 ASP.NET Core 中,內建的 DI 容器提供了三種主要的生命週期,這也是面試時最常被問到的考題:

  • Transient (暫時的):每次請求服務時,都會建立一個新的實例。輕量級無狀態服務適合使用。
  • Scoped (範圍的):在同一個 HTTP Request 範圍內,只會建立一個實例。最常用於資料庫 Context。
  • Singleton (單例的):在整個應用程式啟動到結束,只會有一個實例。適合快取服務。

3. 程式碼實作範例

讓我們來看看如何在 `Program.cs` 中註冊這些服務。以下是一段標準的註冊代碼:

// Program.cs

var builder = WebApplication.CreateBuilder(args);

// 1. 註冊 Transient 服務
builder.Services.AddTransient();

// 2. 註冊 Scoped 服務 (通常用於 DB Context)
builder.Services.AddScoped();

// 3. 註冊 Singleton 服務 (快取)
builder.Services.AddSingleton();

var app = builder.Build();

接著,我們可以在 Controller 的建構子 (Constructor) 中直接注入使用:

// HomeController.cs

public class HomeController : Controller
{
    private readonly IEmailService _emailService;

    // 透過建構子注入 (Constructor Injection)
    public HomeController(IEmailService emailService)
    {
        _emailService = emailService;
    }

    public IActionResult Index()
    {
        _emailService.Send("Test Email");
        return View();
    }
}

4. 常見的錯誤陷阱

在使用 DI 時,最致命的錯誤就是「在 Singleton 服務中注入 Scoped 服務」 (Captive Dependency)。 這會導致 Scoped 服務原本應該跟著 Request 結束而釋放,卻因為被 Singleton 抓住而無法釋放,最終導致記憶體洩漏 (Memory Leak) 或資料庫連線錯誤。

注意: 開發環境下,ASP.NET Core 會主動偵測這種錯誤並拋出例外,但在 Production 環境可能會被忽略,請務必小心。

5. 結論

掌握依賴注入是成為資深 .NET 開發者的必經之路。它不只是一種語法,更是一種架構思維。 希望這篇文章能幫助大家釐清觀念。如果您想深入學習如何設計乾淨架構 (Clean Architecture),歡迎報名我們的進階課程!


想學習更多架構設計嗎?

碩遠學苑「ASP.NET Core 實戰班」現正熱烈招生中,帶你手把手實作企業級專案。

前往課程介紹
洪明義 老師

微軟 MVP / 碩遠科技總經理

專注於 .NET 技術推廣,熱愛分享架構設計與實戰經驗。