Dependency Injection trong C#

Dependency Injection trong C#

March 18, 2025 0 By Nam Vu

Định nghĩa Dependency Injection trong C#

Dependency Injection (DI) là một mẫu thiết kế phần mềm giúp phát triển mã nguồn có độ kết hợp lỏng lẻo (loosely coupled). DI giúp giảm thiểu sự phụ thuộc chặt chẽ giữa các thành phần phần mềm, cải thiện khả năng mở rộng và bảo trì. Ngoài ra, DI còn được gọi là Inversion of Control (IoC) vì nó giúp đảo ngược quyền kiểm soát việc tạo ra các đối tượng phụ thuộc, từ đó hỗ trợ kiểm thử đơn vị (unit testing) một cách hiệu quả.

Cách Dependency Injection hoạt động trong C#

Giả sử một Client class cần sử dụng một Service class, thay vì tạo trực tiếp một đối tượng của Service, Client chỉ cần biết về một interface IService. Khi đó, có thể thay đổi hoặc mở rộng Service mà không ảnh hưởng đến mã nguồn của Client, giúp cải thiện khả năng bảo trì và tái sử dụng mã.

Các loại Dependency Injection trong C#

Có ba phương pháp chính để thực hiện Dependency Injection:

1. Constructor Injection

Trong phương pháp này, dependency được truyền trực tiếp vào constructor của đối tượng khi nó được khởi tạo. Điều này đảm bảo rằng dependency luôn sẵn sàng khi đối tượng chính được sử dụng. Đây là phương pháp phổ biến nhất trong DI.

Ví dụ:

public class Client
{
    private readonly IService _service;

    public Client(IService service)
    {
        _service = service;
    }
}

2. Method Injection

Trong Method Injection, dependency được truyền vào thông qua phương thức thay vì constructor. Phương pháp này ít phổ biến nhưng có thể hữu ích khi chỉ cần một dependency trong một số phương thức cụ thể.

Ví dụ:

public class Client
{
    public void Execute(IService service)
    {
        service.DoSomething();
    }
}

3. Property Injection

Với Property Injection, dependency được thiết lập thông qua thuộc tính (property) của lớp. Điều này giúp khởi tạo dependency một cách lười biếng (lazy loading), tránh việc dependency phải có sẵn ngay từ lúc khởi tạo đối tượng chính.

Ví dụ:

public class Client
{
    public IService Service { get; set; }
}

Phương pháp này hữu ích khi sử dụng cùng với Factory Pattern, giúp giảm sự phụ thuộc trực tiếp giữa các thành phần.

Lợi ích của Dependency Injection

  • Giảm sự phụ thuộc giữa các lớp (decoupling).
  • Tăng khả năng tái sử dụng mã bằng cách trừu tượng hóa các dependency.
  • Cải thiện khả năng bảo trì mã vì dễ dàng thay đổi và mở rộng.
  • Hỗ trợ kiểm thử đơn vị (unit testing) bằng cách dễ dàng thay thế dependency bằng mock object.

Hướng dẫn thiết kế dịch vụ với Dependency Injection

Khi triển khai DI, cần tuân theo một số nguyên tắc sau:

  • Tránh sử dụng lớp tĩnh (static class) hoặc thành viên tĩnh (static members) vì chúng làm mất tính linh hoạt của DI.
  • Hạn chế việc khởi tạo trực tiếp các dependency trong dịch vụ vì điều này làm tăng sự phụ thuộc chặt chẽ.
  • Tạo các dịch vụ nhỏ gọn, có trách nhiệm đơn lẻ (Single Responsibility Principle – SRP) để dễ dàng kiểm thử và bảo trì.
  • Nếu một lớp có quá nhiều dependency, điều đó có thể là dấu hiệu của việc vi phạm SRP. Nên xem xét tách lớp đó thành nhiều lớp nhỏ hơn.

Dependency Injection là một kỹ thuật mạnh mẽ giúp viết mã nguồn dễ bảo trì, mở rộng và kiểm thử trong C#. Bằng cách áp dụng DI, bạn có thể cải thiện tính modularity, reusability, và flexibility của ứng dụng. Dù sử dụng Constructor Injection, Property Injection hay Method Injection, mục tiêu chính vẫn là giảm sự phụ thuộc giữa các thành phần, giúp mã nguồn dễ hiểu và dễ bảo trì hơn.

#ntechdevelopers