Using Dependency Injection (DI) in .NET Core
In this tutorial Using Dependency Injection (DI) in .NET Core I am going to show you how to use Dependency Injection in an .NET Core Project.
When you are creating a .NET Core Project it automatically comes with an Dependency Injection Framework pre-installed, so you don't have to look for any other solutions nor maintain it separately. However, if you wish to use any other framework you can do this anyways, but in this tutorial I will cover only the build in solution. Through this we can keep the dependencies to other frameworks and libraries as small as possible.
First things first, if you want to use Dependency Injection (and you want it :-)), you have to implement the Dependency Inversion Principle, where you rely on abstractions and not concretions. Typically that mean that you have to use interfaces.
In our case we want to create an IPersonPersistence interface which will be used for our Dependency Injection and a concrete implementation of that interface named PersonPersistence. The interface itself only holds one defintion called GetPersons().
namespace MyRESTService.Persistence
{
public interface IPersonPersistence
{
IList<String> GetPersons();
}
}
The concrete implementation of that interface implements that interface like the following example, where three values are returned.
namespace MyRESTService.Persistence
{
public class PersonPersistence : IPersonPersistence
{
public IList<string> GetPersons()
{
return new String[] { "Person1", "Person", "Person3" };
}
}
}
That was the very basic implementation of an interface based Persistence layer. Now we have to tell somewhere the Dependecy Injection Framework where to get the PersonPersistence implementation when the IPersonPersistence is used. This Configuration is done within the Startup.cs file in the ConfigureServices method.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPersonPersistence, PersonPersistence>();
// Add framework services.
services.AddMvc();
}
There are three different ways to register a service - find the reference here.
- Transient - Transient lifetime services are created each time they're requested. This lifetime works best for lightweight, stateless services.
- Scoped - Scoped lifetime services are created once per request.
- Singleton - Singleton lifetime services are created the first time they're requested (or when
ConfigureServices
is run if you specify an instance there) and then every subsequent request will use the same instance.
That's everything you need to prepare for Dependency Injection - it's that easy. Now we want to call the GetPersons() method in our PersonController from the previous tutorial.
All we have to add is a private member for the IPersonPersistence object and a public constructor where the Dependency Injection Framework should pass in our IPersonPersistence implementation.
private readonly IPersonPersistence _personPersistence;
public PersonController(IPersonPersistence personPersistence)
{
_personPersistence = personPersistence;
}
Now we are able to use the concrete IPersonPersistence implementation in our REST functions, in my example I will return the result of the result of GetPersons() in the GET function.
// GET: api/Person
[HttpGet]
public IEnumerable<string> Get()
{
return _personPersistence.GetPersons();
}
If we now start the application and open a browser and navigate to the /api/person URL following results are shown in the browser.
That's it! We now have used Dependency Injection and Depedency Inversion in just a few steps. Imagine you have implemented the Persistence Layer for a SQL Server and you want to switch it to any other Database or Datastorage solution you only have to change the concrete implementation in the service where the IPersonPersistence is configured. All occurrences are automatically resolved by the Dependency Injection Framework.
Happy Coding :-).