dotnet Core and C# Dependency Injection

This is a short introduction into Dependency Injection for those who are new to dotnet core and C#, with an attempt to explain what it is, and how it works.

So, what is Dependency Injection?

DI is a programming method that makes each class independent of the other classes around it. Meaning that we don’t rely on our dependencies working exactly how we expect, and only rely on the API being there to use.

What’s the point?

The two main advantages are:

How to use it in dotnet core?

Fortunately, dotnet core has a built in Dependency Injection engine (referred to as DI, or IoC or Inversion of Control), in fact, it is used by many of the internal dotnet core services and frameworks. The best thing, is that it all exists within Microsoft.Extensions.DependencyInjection, which can be added via nuget if you do not already have it in your project.

How do we know what is and is not a service we should register?

It is quite simple, and there are a few “rules” to help you figure it out:

Example

public void CompletePurchase(double amount, string cardNumber, string address, string city, string name) 
{
  var paymentService = new PaymentService();
  var successfullyCharged = paymentService.Charge(int amount, cardNumber);

  if (successfullyCharged) 
  {
    var shippingService = new ShippingService();
    shippingService.Ship(address, city, name);
  }
}

The problems with the above code are:

What we should be doing is injecting the services via the class constructor, allowing us to swap out the implementations at will, with new implementations or with mock implementations.

public class Checkout
{
  private IPaymentService _paymentService;
  private IShippingService _shippingService;

  public Checkout(IPaymentService paymentService, IShippingService shippingService) 
  {
    _paymentService = paymentService;
    _shippingService = shippingService;
  }

  public void CompletePurchase(double amount, string cardNumber, string address, string city, string name) 
  {
    var successfullyCharged = _paymentService.Charge(int amount, cardNumber);

    if (successfullyCharged) 
    {
      _shippingService.Ship(address, city, name);
    }
  }
}

This code now:

Enter dotnet core

The built-in container is represented by an IServiceProvider implementation that supports constructor injection by default. The classes managed by the built-in IoC container are called services.

ASP.NET Core allows us to register our application services with IoC container, in the ConfigureServices method of the Startup class. The ConfigureServices method includes a parameter of the IServiceCollection interface which is used to register application services

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.Add(new ServiceDescriptor(typeof(IPaymentService), new PaymentService()));      
        services.Add(new ServiceDescriptor(typeof(IShippingService), new ShippingService()));        
    }

}

So IoC and DI in ASP.NET Core and dotnet core in general is very easy, and more or less built in.

Comments

comments powered by Disqus