Zarządzanie cyklem życia zależności to organizacja tworzenia, inicjalizacji, aktualizacji i niszczenia komponentów aplikacji w taki sposób, aby były niezależne od siebie i łatwe do testowania. W tym celu często stosuje się kontenery IoC (Inversion of Control) oraz wzór Dependency Injection (DI).
Kontener IoC pozwala:
Przykład w C# z użyciem Microsoft.Extensions.DependencyInjection:
public interface IMessageSender { void Send(string msg); } public class EmailSender : IMessageSender { public void Send(string msg) { /* wysyłanie emaila */ } } // Rejestracja zależności var services = new ServiceCollection(); services.AddScoped<IMessageSender, EmailSender>(); // Pobieranie instancji var provider = services.BuildServiceProvider(); var sender = provider.GetService<IMessageSender>(); sender.Send("Cześć!");
Kluczowe cechy:
Czym różni się wstrzykiwanie zależności (DI) od wzoru Service Locator, i dlaczego Service Locator uważany jest za antywzór?
Service Locator narusza jawne przekazywanie zależności, sprawia, że kod jest mniej przejrzysty. Lepiej używać DI przez konstruktor lub metody, aby kompilator kontrolował poprawność zależności.
// Źle: Service Locator var sender = ServiceLocator.Get<IMessageSender>(); // Dobrze: przez DI public class MyService { public MyService(IMessageSender sender) { ... } }
Jaka jest różnica między wzorem Singleton a Single Instance w czasie życia w kontenerze DI?
Wzór Singleton jest realizowany ręcznie i nie zależy od kontenera; Single Instance zapewnia instancję z kontenera, co jest bezpieczniejsze dla testów jednostkowych i rozwoju.
Czy należy wstrzykiwać zależności we wszystkich klasach, nawet w prostych narzędziach?
Nie. Narzędzia bez zależności lub słabo powiązane klasy pomocnicze (na przykład klasa stałych matematycznych) nie ma sensu wstrzykiwać DI — to komplikuje kod, nie przynosząc korzyści.