Our Software Design and Development Clinics focus on teaching engineers the real-world development skills that will lead them to be more productive and effective.
Doug and I cover several topics during the clinics, but we try to focus on actually doing things. We want students to develop skill and knowledge, which takes both learning and putting that learning into practice.
When we discuss the basic concepts of good software design and construction, we talk about the concepts of SOLID (an acronym created by Robert Martin).
S – Single Responsibility
O – Open Closed Principle
L – Liskov Substitution
I – Interface Segregation
D – Dependency Inversion
In this post I want to focus on the concept of Dependency Inversion. Dependency Inversion means that our code should depend on interfaces, not the services themselves. In practice, one service should only know about an interface to another service and not the service itself.
To achieve this, we use a basic factory pattern when creating services. Basically, every service will use a factory to gain access to a service instead of just new’ing up a service. Below is an example of what I am talking about.
In our clinics, we intentionally keep as much technology out of them as possible. We are using the most basic parts of .NET. We do this because we want to focus on the concepts and not how to do something with a particular framework.
We hid how we implemented DI behind a base factory (FactoryBase). That allows us to change how we implement our factory pattern without changing the rest of the code. We should be able to change dependency injection technology without changing any of the other code in our system.
To switch our FactoryBase to use .NET Core we should only have to change a couple of methods to use .NET Core’s way of handling dependency injection. In our examples, we have to just use two classes: ServiceProvider and ServiceCollection. To add services to the collection, we’ll create a new ServiceDescriptor and then add that descriptor to the collection.
To create a service from the collection, we’ll just call GetService.
We could also use Unity to do dependency inversion. Unity is a library by the Microsoft Patterns and Practices Team, and it is a good way to do dependency inversion on the .NET Framework. Here’s an example of dependency inversion in Unity:
Regardless of which technology we use to do dependency injection, it is nice to have hidden that choice behind our FactoryBase class. That allows us to easily change our technology.
This is a good example of the single responsibility “S” principle of SOLID. Each module should have only one reason to change. Our FactoryBase has only one reason to change, it will only change if we change our dependency injection.
If you liked what you have read here, consider signing up for our Software Design and Development Clinic.
For more fun, follow me on Twitter at @chadmichel.