Zasada Inwersji Zależności (DIP) — to zasada architektoniczna, wg której:
Oznacza to, że logika biznesowa (np. serwis do obsługi zamówień) nie powinna znać i bezpośrednio używać konkretnej implementacji infrastruktury (np. klasy realizującej wysyłkę maili), lecz pracować przez abstrahencję (interfejs), który jest wstrzykiwany przez mechanizm kontenera DI lub ręcznie.
Przykład kodu w C#:
public interface IEmailSender { void Send(string to, string message); } public class SmtpEmailSender : IEmailSender { public void Send(string to, string message) { // Implementacja wysyłki emaila } } public class OrderService { private readonly IEmailSender _emailSender; public OrderService(IEmailSender emailSender) { _emailSender = emailSender; } public void PlaceOrder(string customer) { // logika biznesowa _emailSender.Send(customer, "Twoje zamówienie zostało złożone!"); } }
Kluczowe cechy:
Czy DIP to tylko wstrzykiwanie zależności przez konstruktor?
Nie. DIP dotyczy oddzielenia abstrahencji od implementacji. Wstrzykiwanie zależności (Dependency Injection, DI) to tylko narzędzie, za pomocą którego realizuje się DIP. DIP można wdrożyć także bez kontenera DI, ręcznie zapewniając separację abstrahencji i szczegółów.
Czy w przypadku jednej implementacji interfejsu DIP jest obowiązkowe?
Tak, zasada nadal ma zastosowanie, jeśli istnieje możliwość rozszerzenia. Wprowadzenie abstrahencji przygotowuje system na zmiany wymagań bez modyfikacji kodu wysokiego poziomu. Nawet przy jednej implementacji interfejsu, słabe powiązanie ułatwia testowanie i rozwój systemu.
Czy można naruszyć DIP, używając logiki w fabrykach lub lokalizatorach serwisów?
Tak. Jeśli fabryka lub lokalizator serwisów zna szczegóły implementacji i dynamicznie wiąże je bez użycia interfejsu po stronie klienta, DIP jest naruszane, mimo zewnętrznej obecności abstrahencji.