文章

第22天:中介軟體與服務注入

課程簡介

在今天的課程中,我們將探討 中介軟體(Middleware)服務注入(Dependency Injection, DI),這是 ASP.NET Core 的兩個關鍵功能。中介軟體允許開發者攔截和修改 HTTP 請求或回應,服務注入則提供了一種管理和注入依賴的有效方式,使應用程式更加模組化和易於測試。


學習目標

  • 了解中介軟體的概念與工作原理
  • 學習如何在 ASP.NET Core 中建立與使用中介軟體
  • 掌握服務注入的基本概念與應用
  • 學會如何在應用程式中注入自訂服務

課程內容

1. 中介軟體(Middleware)

中介軟體 是 ASP.NET Core 中的請求處理管道中的一部分。每個中介軟體都是獨立的模組,它可以處理請求和回應,並將控制權傳遞給管道中的下一個中介軟體。

中介軟體的工作原理:

當應用程式接收到一個 HTTP 請求時,請求會按照管道中的順序通過一系列的中介軟體,每個中介軟體都可以檢查、修改請求或回應,或者直接處理請求並結束流程。

中介軟體範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class RequestLoggingMiddleware
{
    private readonly RequestDelegate _next;

    public RequestLoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        Console.WriteLine($"Request: {context.Request.Method} {context.Request.Path}");
        await _next(context);
        Console.WriteLine($"Response: {context.Response.StatusCode}");
    }
}

Startup.cs 中註冊中介軟體:

1
2
3
4
5
6
7
8
9
public void Configure(IApplicationBuilder app)
{
    app.UseMiddleware<RequestLoggingMiddleware>();
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

這段程式碼展示了如何建立一個簡單的中介軟體來記錄 HTTP 請求與回應,並將其註冊到 ASP.NET Core 應用程式的管道中。


2. 內建中介軟體

ASP.NET Core 提供了許多內建的中介軟體,用來處理常見的任務,例如靜態檔案服務、錯誤處理、身份驗證等。

常見的內建中介軟體:

  • UseStaticFiles:提供靜態檔案支援,如 CSS、JS 檔案。
  • UseRouting:啟用路由功能。
  • UseAuthentication:啟用身份驗證機制。
  • UseAuthorization:啟用授權功能。

使用範例:

1
2
3
4
5
6
7
8
9
10
11
public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); // 提供靜態檔案
    app.UseRouting();      // 啟用路由
    app.UseAuthentication(); // 啟用身份驗證
    app.UseAuthorization();  // 啟用授權
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

3. 服務注入(Dependency Injection, DI)

依賴注入 是 ASP.NET Core 的一個核心功能,它允許開發者將對象的依賴從應用程式的其他部分分離出來。這樣做可以提升應用程式的可測試性和靈活性,因為不同部分之間的依賴關係可以輕鬆地管理和替換。

服務注入的工作原理:

ASP.NET Core 提供了一個內建的 IoC 容器,開發者可以在 Startup.cs 中將服務註冊到容器中,然後在應用程式的任何地方請求這些服務。

註冊服務:

Startup.cs 中,我們可以使用 ConfigureServices 方法來註冊服務:

1
2
3
4
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IMyService, MyService>();
}

使用服務注入:

在控制器或其他類別中,可以通過建構函式注入的方式使用服務:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class HomeController : Controller
{
    private readonly IMyService _myService;

    public HomeController(IMyService myService)
    {
        _myService = myService;
    }

    public IActionResult Index()
    {
        var result = _myService.GetData();
        return View(result);
    }
}

在這個範例中,HomeController 需要一個 IMyService 物件,我們通過建構函式注入的方式將這個服務傳遞給控制器。


4. 服務的生命週期

ASP.NET Core 支援三種不同的服務生命週期:

  • 瞬態(Transient):每次請求服務時,皆會產生一個新的實例。
  • 範圍(Scoped):每個 HTTP 請求共享同一個服務實例。
  • 單例(Singleton):應用程式的生命週期內,所有請求共享同一個服務實例。

註冊服務時指定生命週期:

1
2
3
services.AddTransient<IMyService, MyService>();  // 瞬態
services.AddScoped<IMyService, MyService>();    // 範圍
services.AddSingleton<IMyService, MyService>(); // 單例

選擇合適的生命週期非常重要,應根據服務的使用情境來決定。例如,數據庫連接通常註冊為範圍(Scoped),因為每個請求都應該使用不同的連接實例。


5. 自訂服務的建立與注入

除了內建的服務,開發者也可以自訂服務,並將其注入到應用程式的各個部分。

建立自訂服務:

1
2
3
4
5
6
7
8
9
10
11
12
public interface IMyService
{
    string GetData();
}

public class MyService : IMyService
{
    public string GetData()
    {
        return "這是來自 MyService 的資料";
    }
}

註冊與注入自訂服務:

1
2
3
4
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IMyService, MyService>();
}

然後在控制器中注入並使用這個自訂服務:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MyController : Controller
{
    private readonly IMyService _myService;

    public MyController(IMyService myService)
    {
        _myService = myService;
    }

    public IActionResult Index()
    {
        var data = _myService.GetData();
        return View(data);
    }
}

這樣的架構讓應用程式的依賴關係更加清晰和靈活,並提升了可測試性。


實作練習

  1. 建立中介軟體
    • 創建一個自訂中介軟體來記錄 HTTP 請求的資訊,並將其加入到管道中。
    • 試著調整中介軟體的順序,觀察對請求處理流程的影響。
  2. 服務注入
    • 建立一個自訂服務,該服務提供一些數據,並將其注入到控制器中。
    • 將服務註冊為不同的生命週期(Transient、Scoped、Singleton),並測試其行為差異。

教學重點

  • 了解中介軟體在 ASP.NET Core 中的角色,學會如何建立與使用自訂中介軟體。
  • 掌握服務注入的概念,學會如何使用內建的 IoC 容器來管理應用程式中的依賴關係。
  • 理解服務的不同生命週期,以及如何根據應用場景選擇合適的生命週期。

在接下來的課程中,我們將探討 身份驗證與授權 的核心概念,並學習如何在 ASP.NET Core 中進行應用程式的安全性配置。

本文章以 CC BY 4.0 授權