Dependency Injection and Inversion of Control on .Net Core

Do you know about the terms Dependency Inject and/or Inversion of Control? No? Let’s go to talk about it! I’ll explain to you how and why do you need to use these patterns. And finally, we’ll develop a .Net Core simple application that uses these concepts.

Firstly, what do you think to learn the theory? Let’s start learning a little bit about Dependency Injection!

Dependency Injection

A dependency is an object that your class needs to do the work, in other words, this object isn’t created inside your class. The dependency is injected into a class that uses it, so the dependency is required to be external. The object instantiation (that is the dependency) must not be inside the class, but outside it. Look below a simple example:

In this case, when I instantiate the LeaderboardServiceManager class, I need to pass an IMapper type instantiate. Look, the constructor receives a parameter (mapper) and its value is set to a variable (_mapper) which will be used in the other functions of this class.

Benefits of using it:

  • Low coupling
  • Simplicity
  • Ease of maintenance
  • Ease to learn about the code/project
  • Ease to test your code

Exists three most common types of Dependency Injection:

1) Constructor

In this case, I receive an ISmtpClient type instantiate by the constructor to use it in some function of my class.

2) Getter and Setter

We have a property SmtpClient of ISmtpClient type, so to this property must be attributed a valid value.

3) Interface Implementation

4) Service locator

First, we should have a class to register and provides the instances
Second, in another part of your code, we can register all the instances
And finally, we can use it like this

And next, let’s go to talk about the Inversion of Control!

Inversion of Control

And now, we arrived where we really want to: IoC attends one of the S.O.L.I.D. principles, the Dependency Inversion, and that explains how it is so important. Let’s review it.

S.O.L.I.D. is an acronym for five important design principles when you work with OOP (Object Oriented Programming), and each letter means:

  • S: Single responsibility
  • O: Open closed
  • L: Liskov substitution
  • I: Interface segregation
  • D: Dependency inversion

Now, I think we have all of the knowledge to do something more practical. Let’s go?

Development

Creating the project

Next, name your project, select a folder (or accept the default option), name your solution (or accept the default option) and click on the ‘Create’ button:

Now, choose the ‘API’ option, like below and click on Create button:

Dividing our project into layers

Let’s make three other folders, called Domain, Services, and Dependencies:

  • Controllers: Layer that contains classes responsible for responding for request API
  • Dependencies: Layer responsible to do the Inversion of Control of project
  • Domain: Layer containing the model classes of the project
  • Services: Layer that contains the logic rules

Into the Domain folder, let’s make more two sub-folder, called Entities and Interfaces. And into a sub-folder Entities, make another sub-folder called DTOs (Data Transfer Objects):

  • Entities: Has the anemic classes
  • Entities.DTOs: Has classes to receive data in controllers
  • Interfaces: Contract classes

Building our domain layer

Club.cs is the model that we will return.

Second, let’s create a ClubDTO class, into the DTOs sub-folder. Into this entity will have three properties, called Name, PointsEarned, and GamesPlayed.

ClubDTO.cs is the model that we will receive in the controller.

And finally, let’s create the IServiceClube interface. It has a contract reference to calculate the percentage of achievement, like below:

Building our service layer

When we put the inheritance in this class, we need to implement the contracts, like below:

Now, let’s implement the logic:

Building our dependency layer

Now, we go to use a resource called Extension Methods. This resource allows us to “add” methods to existing types without creating a new derived type. In this case, we extended the IServiceCollection type. This type provides an intern container service called IServiceProvider which allows us to register our dependencies. So, we can create a static method into the dependency class, like this:

.NET Core provides three kinds of dependency injection, based in your lifetimes:

  • Transient: services that will be created each time they are requested
  • Scoped: services that will be created once per client request (connection)
  • Singleton: services that will be created only at the first time they are requested

And now, we add our dependencies. In this project, we have only one dependency that reference to our Service/Logic, and we’ll use the Transient Lifetime:

Building our controller layer

What do you think about using what we learned about Dependency Injection? Let’s use the dependency injection by constructor to use the services we created before, like below:

And finally, let’s create our Action Method (I will not explain in more detail because this is another subject). Attention for the red highlight, it is when we use the dependency injection attribute:

Final adjustments

And now, our application can run without any problem!

The execute

https://localhost:44343/api/club/CalculatePercentage?name=Test%20Club&pointsEarned=10&gamesPlayed=4

Attention for your application port, in my case, it is 44343.

Let’s see the data that we receive:

And note that the ServiceClub was instantiated without our interference/command.

And the result:

Conclusion

The code you can find here.

Bachelor in Computer Science, MBA in Software Architecture and .NET Developer.