Using ServiceDescriptor To Register Dependencies In ASP.NET Core

In this article, we’ll look at how we can register dependencies using ServiceDescriptor and where this method would be be useful.

Introduction

Registering dependencies in ASP.NET Core is really easy with the built-in DI Container. You just have to add them into the IServiceCollection instance that is passed in using the appropriate Service Lifetimes and to do that, you can use the provided extension methods. It's pretty simple. But sometimes, you may want to register dependencies using ServiceDescriptor. 

Creating the ServiceDescriptor Instance

You have to set the Implementation Type (the interface), the Service Type  (the implementation of the interface), and the Service Lifetime of the service when you create the ServiceDescriptor. There are 4 ways of creating a new ServiceDescriptor instance.

You can new up an instance of the ServiceDescriptor class using one of its constructors like below.

You need to supply the Implementation Type, Service Type, and the Service Lifetime as parameters.

  1. var oneService = new ServiceDescriptor(typeof(IOneService), typeof(OneService), ServiceLifetime.Scoped);  

Another way of creating an instance is by using the Describe() static method. Again, you have to provide the Implementation Type, Service Type, and the Service Lifetime as parameters.

  1. var twoService = ServiceDescriptor.Describe(typeof(ITwoService), typeof(TwoService), ServiceLifetime.Scoped);  

Since the Service Lifetimes is a must to provide when creating the ServiceDescriptor, there are static methods available for each of the Service Lifetimes on the ServiceDescriptor Class. You can use them as well.

  1. var threeService = ServiceDescriptor.Scoped(typeof(IThreeService), typeof(ThreeService));  

Also, you can use the generic version of the static methods so that you can exclude the typeof operator.

  1. var fourService = ServiceDescriptor.Scoped<IFourService, FourService>()  

Once you have created the ServiceDescriptor instance, you need to add it to the Service Collection by using the Add() method.

  1. services.Add(oneService);  
  2. services.Add(twoService);  

You will rarely need to register dependencies using this method, but it's important to know when you need to use and where.

When to Use ServiceDescriptor to Register Dependencies

There are a couple of instances where you need to create a ServiceDescriptor instance to register dependencies.

Replacing an Already Registered Dependency

If you ever want to replace an already registered dependency, you can do it in ASP.NET Core dependency container. The Service Collection provides a Replace() method under Microsoft.Extensions.DependencyInjection.Extensions namespace which only accepts a ServiceDescriptor.

  1. services.Replace(ServiceDescriptor.Scoped<IFourService, FourService>());  

Safely Register Multiple Implementations of a Dependency

You can register multiple implementations of a single Implementation Type in ASP.NET Core. But there is a possibility of duplicate registrations. ASP.Net Core will allow duplicate registrations to work and there can be scenarios where using duplicate registrations can be troublesome.

To avoid this issues you can use TryAddEnumerable() method on the ServiceCollection. This method accepts a single ServiceDescriptor Instance or an Enumerable of ServiceDescriptor. When using this method, any duplicate registrations will be skipped,

  1. services.TryAddEnumerable(ServiceDescriptor.Scoped<IThreeService, ThreeService>());  
  2. //or  
  3. services.TryAddEnumerable(new[] {  
  4.                 ServiceDescriptor.Scoped<IThreeService, ThreeService>(),  
  5.                 ServiceDescriptor.Scoped<IThreeService, AwesomeThreeService>(),  
  6.                 ServiceDescriptor.Scoped<IThreeService, SuperAwesomeThreeService>()  
  7.             });   

Summary

In this article, we learned about ServiceDescriptor in ASP.NET Core and how to use them when registering dependencies and also where using instances of ServiceDescriptor is useful. All the code sample in this article is available for download and also available in GitHub under the following repository