Sobes.tech
Junior

What types of dependency injection do you know?

sobes.tech AI

Answer from AI

There are three main types of dependency injection:

  1. Constructor Injection: Dependencies are provided to the class through its constructor. The class cannot be created without supplying all necessary dependencies. This ensures a clear specification of dependencies and facilitates testing.

    public class SomeService {
    
        private final Dependency dependency;
    
        public SomeService(Dependency dependency) { // Constructor injection
            this.dependency = dependency;
        }
    
        public void doSomething() {
            dependency.execute();
        }
    }
    
  2. Setter Injection: Dependencies are provided to the class via public setter methods. This makes the class more flexible in terms of configuration but does not guarantee the provision of all dependencies upon object creation.

    public class AnotherService {
    
        private Dependency dependency;
    
        public void setDependency(Dependency dependency) { // Setter injection
            this.dependency = dependency;
        }
    
        public void doSomethingElse() {
            if (dependency != null) {
                dependency.execute();
            } else {
                // Handle absence of dependency
            }
        }
    }
    
  3. Interface Injection: A less common type where the dependent class must implement a specific interface that provides a setter for the dependency. The injector uses this interface to provide the dependency.

    // Interface defining the method for dependency injection
    public interface DependencyInjectable {
        void setDependency(Dependency dependency);
    }
    
    public class YetAnotherService implements DependencyInjectable {
    
        private Dependency dependency;
    
        @Override
        public void setDependency(Dependency dependency) { // Interface method implementation
            this.dependency = dependency;
        }
    
        public void performAction() {
            if (dependency != null) {
                dependency.execute();
            }
        }
    }
    

Comparison of methods:

Method Advantages Disadvantages Typical use cases
Constructor Clear dependency specification, immutability Multiple dependencies can lead to "bulky" constructors Mandatory dependencies, creation of immutable objects
Setter Optional dependencies, configuration flexibility Does not guarantee dependency presence, mutable state Optional dependencies, inheritance, post-creation configuration
Interface Less common Additional complexity Rare scenarios requiring a standardized injection method

The most preferred approach in most cases is constructor injection, especially for mandatory dependencies, as it explicitly defines the class contract and promotes creating objects in a correct state. Setter injection is convenient for optional dependencies or when there are many dependencies to avoid long constructors. Interface injection is used less frequently and can be useful in specific frameworks or when standardizing the injection process.