Dependency Injection (DI) is a programming concept that aims to reduce the coupling between components in a system, making them more interchangeable, extensible, and easier to test. In DI, objects are passed to components through an external provider (injector) instead of being created within the component itself.
At the core of DI is the principle of Inversion of Control (IoC). Instead of a component creating its dependencies, they are provided to it from the outside. This can be achieved through constructors, methods, or other mechanisms.
Let's consider a simple example in a programming language like Java.
Example without DI:
public class UserService {
private UserRepository userRepository;
public UserService() {
this.userRepository = new UserRepository();
}
public void saveUser(User user) {
userRepository.save(user);
}
}
In this example, UserService owns UserRepository. The issue is that UserService is tightly coupled to a specific implementation of UserRepository, making the code less flexible, harder to test, and less replaceable.
Example with DI:
public class UserService {
private UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void saveUser(User user) {
userRepository.save(user);
}
}
In this example, UserService receives UserRepository through its constructor. This makes the code more flexible, as now you can easily change or replace the UserRepository without impacting the UserService. It simplifies testing and maintenance.
DI makes programs more flexible, facilitates testing, and contributes to code maintainability. This approach is particularly valuable in large projects with many interdependent components.