Sobes.tech
Junior

What types of dependency injection do you know?

sobes.tech AI

Answer from AI

There are three main types:

  1. Field Injection: The dependency is injected directly into a class field using an annotation (e.g., @Autowired in Spring). It is easy to use but complicates modular testing and violates the single responsibility principle by hiding dependencies.

    // Example of Field Injection
    public class MyService {
        // Dependency is injected directly into the field
        @Autowired
        private MyRepository repository;
    
        public void doSomething() {
            repository.getData();
        }
    }
    
  2. Setter Injection: The dependency is injected via a public setter method. It allows optional dependencies (not mandatory to set), convenient for changing dependencies at runtime (though rarely used). It does not create a mandatory dependency when creating the object.

    // Example of Setter Injection
    public class MyService {
        private MyRepository repository;
    
        // Dependency is injected via setter
        @Autowired
        public void setRepository(MyRepository repository) {
            this.repository = repository;
        }
    
        public void doSomething() {
            repository.getData();
        }
    }
    
  3. Constructor Injection: The dependency is injected via the constructor argument. It is preferred because it enforces the dependency's necessity (the object cannot be created without it), simplifies modular testing (easy to pass mock objects), and clearly declares the class's needs. It makes objects immutable after creation if fields are final.

    // Example of Constructor Injection
    public class MyService {
        private final MyRepository repository; // Field can be final
    
        // Dependency is injected via constructor
        @Autowired // In newer Spring versions, the @Autowired annotation can be omitted for a single constructor
        public MyService(MyRepository repository) {
            this.repository = repository;
        }
    
        public void doSomething() {
            repository.getData();
        }
    }
    

Comparison table:

Injection Type Dependency Mandatory Ease of Use Testability Immutability
Field Optional (hidden) High Low No
Setter Optional Medium Medium No
Constructor Mandatory Medium High Possible

In most cases, constructor injection is recommended.