Skip to content

Cum Să Implementezi Dependency Injection — Inversarea Controlului

DodaTech Updated 2025-01-15 2 min read

In this tutorial, you'll learn about Cum Să Implementezi Dependency Injection. We cover key concepts, practical examples, and best practices.

Vei învăța cum să implementezi Dependency Injection (DI) și Inversion of Control (IoC) pentru a crea cod decuplat, testabil și ușor de întreținut.

Problema

Clasele care creează direct dependințele interne sunt greu de testat și de modificat. Orice schimbare într-o dependință necesită modificarea clasei părinte.

Abordarea Greșită

Crearea directă a dependințelor în constructor.

// Greșit: cuplare strânsă
class UserService {
    private Database database;

    public UserService() {
        this.database = new Database(); // greu de testat
    }
}

Abordarea Corectă

Injectarea dependințelor prin constructor.

// Corect: dependințe injectate
class UserService {
    private final Database database;
    private final EmailService emailService;

    public UserService(Database database, EmailService emailService) {
        this.database = database;
        this.emailService = emailService;
    }
}

Rezolvare Pas cu Pas

1. Identifică dependințele

Separă logica de business de crearea obiectelor.

from abc import ABC, abstractmethod

class UserRepository(ABC):
    @abstractmethod
    def find_by_id(self, user_id: int):
        pass

class EmailSender(ABC):
    @abstractmethod
    def send(self, to: str, subject: str, body: str):
        pass

2. Injectează prin constructor

class UserService:
    def __init__(self, repo: UserRepository, email: EmailSender):
        self._repo = repo
        self._email = email

    def register_user(self, user_id: int, email: str):
        user = self._repo.find_by_id(user_id)
        self._email.send(email, "Bun venit", "Contul tău a fost creat")

3. Configurează containerul DI

# Simple DI container
class Container:
    def __init__(self):
        self._services = {}

    def register(self, interface, implementation):
        self._services[interface] = implementation

    def resolve(self, interface):
        return self._services[interface]()

# Configurare
container = Container()
container.register(UserRepository, DatabaseRepository)
container.register(EmailSender, SMTPEmailSender)

# Folosire
service = UserService(
    container.resolve(UserRepository),
    container.resolve(EmailSender)
)

4. Testează cu mock-uri

from unittest.mock import Mock

def test_register_user():
    mock_repo = Mock()
    mock_email = Mock()
    service = UserService(mock_repo, mock_email)

    service.register_user(1, "test@example.com")

    mock_repo.find_by_id.assert_called_once_with(1)
    mock_email.send.assert_called_once()

Sfaturi de Prevenție

  • Preferă constructor injection în loc de setter injection
  • Folosește un framework DI (Spring, Google Guice, FastAPI) în proiecte mari
  • Nu injecta prea multe dependințe într-o clasă (semn că clasa face prea multe)

Greșeli Comune

  1. Injectarea prea multor dependințe într-o singură clasă
  2. Service Locator anti-pattern în loc de DI propriu-zis
  3. Instanțierea manuală a dependințelor când există un container DI
  4. Dependințe ciclice care nu pot fi rezolvate de container
  5. Injectarea de obiecte mutable partajate între mai multe clase

Întrebări Frecvente

### Ce este Dependency Injection?

Dependency Injection este un pattern în care obiectele primesc dependințele din exterior, în loc să le creeze intern, facilitând testarea și întreținerea.

Care este diferența dintre DI și IoC?

IoC (Inversion of Control) este principiul general prin care controlul fluxului este inversat. DI este o implementare specifică a IoC.

Ce framework-uri DI există?

Spring (Java), Google Guice (Java), Unity (.NET), Dagger (Android), FastAPI (Python), Angular (TypeScript).

Construit de dezvoltatorii Doda Browser, DodaZIP și Durga Antivirus Pro. Uneltele DodaTech folosesc DI pentru module extensibile și testabile.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro