Setter Injection (còn gọi Property Injection) tiêm dependency thông qua property public có getter/setter. Dependency là tùy chọn và có thể thay đổi sau khi đối tượng được tạo.
Ví dụ hoàn chỉnh
// 1. Interface dịch vụ
public interface IService
{
string ServiceMethod();
}
public class ClaimService : IService
{
public string ServiceMethod() => "ClaimService is running";
}
public class AdjudicationService : IService
{
public string ServiceMethod() => "AdjudicationService is running";
}
// 2. Consumer có property public
public class BusinessLogic
{
private IService _service;
public IService Service
{
get => _service;
set => _service = value;
}
public void Execute()
{
if (_service == null)
throw new InvalidOperationException("Service chưa được inject.");
Console.WriteLine($"Setter Injection => Current Service: {_service.ServiceMethod()}");
}
}
// 3. Sử dụng
class Program
{
static void Main()
{
var logic = new BusinessLogic();
logic.Service = new ClaimService(); // Inject qua property
logic.Execute();
logic.Service = new AdjudicationService(); // Thay đổi service lúc runtime
logic.Execute();
Console.ReadLine();
}
}
Ưu / Nhược điểm
| Ưu điểm | Nhược điểm |
|---|---|
| Đơn giản, dễ hiểu | Dependency không bắt buộc -> dễ gây NullReferenceException |
| Cho phép thay đổi dependency lúc runtime | Làm mờ contract của class (không rõ class cần gì để hoạt động) |
| Hữu ích cho optional dependencies | Khó test hơn Constructor Injection |
| Tương thích với serialization / UI frameworks (WPF, Blazor...) | Vi phạm nguyên tắc "Explicit Dependencies Principle" |
Khi nào nên dùng?
- Dependency thực sự là tùy chọn (optional) và class vẫn hoạt động nếu thiếu.
- Cần gán dependency sau khi xây dựng object (ví dụ: trong Blazor component, WPF ViewModel).
- DI Container không hỗ trợ constructor injection cho loại đối tượng đó.
Best practice: Luôn kiểm tra null trước khi dùng property đã inject, hoặc gán giá trị mặc định (Null Object Pattern). Ưu tiên Constructor Injection cho mandatory dependencies.