有了 場務(就像 DI Container),導演只要說:「我要一張椅子。」場務就會自動知道要去哪個部門、怎樣一層層處理,最後把椅子交到導演手上。導演完全不用管細節,專心拍戲。
📑 DI Container是什麼 DI Container 是一個框架或工具,用來自動管理物件的依賴。它的核心思想是: - 反轉控制(IoC):物件不再自己建立依賴,而是由容器負責提供。 - 集中管理:所有依賴關係在容器中註冊,統一配置。 - 可測試性:因為依賴可以替換,單元測試更容易。 - 可維護性:減少耦合,系統更容易擴展。
在 C# 中,DI Container 已經是 ASP.NET Core 的標準配置。
💻 沒有 DI Container 的 C# 範例
// 沒有 DI Container,自己 new 一連串依賴 public class Database { public void Query() => Console.WriteLine("Querying database..."); }
public class Repository { private Database _db;
public Repository() { _db = new Database(); // 直接 new }
public void GetData() => _db.Query(); }
public class Service { private Repository _repo;
public Service() { _repo = new Repository(); // 直接 new }
public void Process() => _repo.GetData(); }
public class Controller { private Service _service;
public Controller() { _service = new Service(); // 直接 new }
public void HandleRequest() => _service.Process(); }
var controller = new Controller(); controller.HandleRequest();
問題: - 每個類別都直接 new 依賴,耦合度極高。 - 如果要替換 Database,就要修改 Repository、Service、Controller。 - 測試時難以注入假物件。
💻 有 DI Container 的 C# 範例 // 定義介面 public interface IDatabase { void Query(); }
public class Database : IDatabase { public void Query() => Console.WriteLine("Querying database..."); }
public class Repository { private readonly IDatabase _db; public Repository(IDatabase db) => _db = db; public void GetData() => _db.Query(); }
public class Service { private readonly Repository _repo; public Service(Repository repo) => _repo = repo; public void Process() => _repo.GetData(); }
public class Controller { private readonly Service _service; public Controller(Service service) => _service = service; public void HandleRequest() => _service.Process(); }
// 使用 DI Container var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IDatabase, Database>(); builder.Services.AddTransient<Repository>(); builder.Services.AddTransient<Service>(); builder.Services.AddTransient<Controller>();
var app = builder.Build();
var controller = app.Services.GetRequiredService<Controller>(); controller.HandleRequest();
好處: - 解耦:Controller 不需要知道 Service 如何建立,Service 不需要知道 Repository 如何建立。 - 集中管理:只要在容器中註冊一次,整個系統就能自動注入。 - 靈活替換:要改用 MockDatabase,只需修改容器設定,不用改任何類別。
🎬 比喻:導演與場務 - 沒有 DI Container:導演要自己跑去材料部、工具部、道具部,逐層找資源,浪費時間。 - 有 DI Container:導演只要告訴場務需要什麼,場務就會自動去各部門協調,把完整的道具交到導演手上。
這個比喻突顯了 DI Container 的威力:它能處理多層依賴,讓開發者專心在「拍戲」(業務邏輯),而不用操心「找道具」(建立依賴)。
🎯 總結 DI Container 的價值在於: - 減少耦合,讓系統更乾淨。 - 集中管理依賴,維護更容易。 - 靈活擴展,只要修改容器設定,就能替換或新增功能。
它就像程式設計的「場務」,幫你準備好所有依賴,讓系統更高效、更可維護。