Keyed Dependency Injection Services

Henrique Siebert Domareski
4 min readDec 22, 2023

Keyed Dependency Injection (DI) Services is a new .NET 8 feature, that allows you to register and retrieve DI services using keys. With that, you can scope how you register and consume services. In this article, I present how to use this feature.

For demonstration purposes, I created an ASP.NET Core Web API project, using the Visual Studio 2022. This project contains an interface IService, which contains the method Execute, and there are three classes that implement this interface, and return a message saying that the service X was executed. This is the IService interface:

public interface IService
{
string Execute();
}

These are the classes that implement the interface IService:

public class ServiceA : IService
{
public string Execute()
{
return "Service A was executed.";
}
}

public class ServiceB : IService
{
public string Execute()
{
return "Service B was executed.";
}
}

public class ServiceC : IService
{
public string Execute()
{
return "Service C was executed.";
}
}

If you are not familiar with DI, I recommend checking the Dependency Injection and Service Lifetimes in .NET Core article.

Registering Multiple Services using the same Interface

When working with the built-in .NET DI container, to register multiple services using the same interface, it’s possible to register like this:

builder.Services.AddScoped<IService, ServiceA>();
builder.Services.AddScoped<IService, ServiceB>();
builder.Services.AddScoped<IService, ServiceC>();

But then when you use the IService in your classes/methods like in the example below, the type that is always going to be used is the ServiceC, because this is the latest type that was registered in the DI container. For example:

When making a request to this endpoint, you can debug and see the service that is being used:

This will be the result when making a request to this endpoint:

A way to solve this problem is by using an IEnumerable<T>, which will retrieve all the other services. For example:

Then you can select the service from this list, for example, in the example below I’m selecting the type ServiceB:

public DemoController(IEnumerable<IService> services)
{
_service = services.OfType<ServiceB>().FirstOrDefault();
}

When making a request to this endpoint, this will be the response:

Keyed DI Services

With Keyed DI Services, introduced with .NET 8, it’s now possible to register multiple types that implement the same interface, by setting a key in the registration of the services and using this key to specify which service you want to use. For that, I created an Enum that will be used for the keys:

public enum DIKey
{
ServiceA,
ServiceB,
ServiceC
}

And in the Program.cs I registered the services using a key (the key can be also a string):

  • On line 1 there is the register for ServiceA, using the key ServiceA.
  • On line 2 there is the register for ServiceB, using the key ServiceB.
  • On line 3 there is the register for ServiceC, using the key ServiceC.

In this example, I used the AddKeyedScoped registration method, but you can also make use of other lifetimes, such as AddKeyedTransient or AddKeyedSingleton.

Then you can specify the key by using the FromKeyedServices attribute. For example, below you can see the DemoController, which contains three endpoints, each one using a different service:

  • On line 7, for the ServiceA method, is set the key ServiceA.
  • On line 16, for the ServiceB method, the key ServiceB.
  • On line 25, for the ServiceC method, the key ServiceC.

This means that when a request is made to these endpoints, the service that will be used is the service that contains the specified key. For example, below you can see three requests executed in sequence, and the responses:

Conclusion

Keyed Dependency Injection Services provides a mechanism for managing multiple implementations of the same interface by using keys, providing a flexible approach when you need to have multiple services that implement the same interface.

This is the link for the project in GitHub: https://github.com/henriquesd/KeyedDIServices

If you like this project, I kindly ask you to give a ⭐️ in the repository.

Thanks for reading!

--

--