Maintainability is the main purpose of DI.
- An excellent way to make code more maintainable is through loose coupling
- Dependency Injection is a set of software design principles and patterns that enables you to develop loosely coupled code.
- Loose coupling Mantra - Program to an interface, not an implementation.
- Loose coupling provides many benefits: code becomes easier to develop, maintain, and extend, and it becomes more TESTABLE. It’s not even particularly difficult.
- We program against interfaces, not concrete implementations. The only major obstacle is figuring out how to get hold of instances of those interfaces.
- DI surmounts this obstacle by injecting the DEPENDENCIES from the outside. CONSTRUCTOR INJECTION is the preferred method of doing that.
- Testability and Unit tests - it’s only possible to write unit tests when the unit in question can be properly isolated from its dependencies.
- We, developers, gain control by removing a class’s control over its DEPENDENCIES. This is an application of the SINGLE RESPONSIBILITY PRINCIPLE.
- Classes shouldn’t have to deal with the creation of their DEPENDENCIES.

Just like the kid and parents above - Classes should rely on infrastructure to provide necessary services.
Do I need to mock .NET BCL?
- The .NET BCL consists of many assemblies. Every time you write code that uses a type from a BCL assembly, you add a dependency to your module. In the previous section, we discussed how loose coupling is important and how programming to an interface is the cornerstone. Does this imply that you can’t reference any BCL assemblies and use their types directly in your application?
- You don’t have to treat all DEPENDENCIES equally. Many types in the BCL can be used without jeopardizing an application’s degree of coupling — but not all of them.
- It can be helpful to categorize your DEPENDENCIES into STABLE DEPENDENCIES and VOLATILE DEPENDENCIES.
- The DEPENDENCY doesn’t yet exist or is still in development.
- The DEPENDENCY isn’t installed on all machines in the development organization
- The DEPENDENCY introduces a requirement to set up and configure a runtime environment for the applications
- We inject VOLATILE DEPENDENCIES into a class’s constructor.
Further topics:
- Liskov substitution principle - we should be able to replace one implementation of an interface with another without breaking either the client or the implementation
- Decorator Design Pattern - intercepting one implementation with another implementation of the same interface
- Composite design pattern
- Adapter design pattern
Read more