| Muhammad Waseem

About Newsletter
Books
30 .NET Tips
Sponsorship
Keyed Service Dependency Injection in .NET
Jun 24, 2024
3 min read

Keyed Service Dependency Injection in .NET

Sponsor this Newsletter

If you are unaware of the concept of Dependency Injection read this article :

EP 62: Dependency Injection Explained in .NET

Keyed Services in .NET 8

Keyed service retrieves the dependency using a key when an interface simply has multiple implementations. This concept was introduced in .NET 8.

Suppose we have the following piece of code where we have two classes implementing the same interface :

public interface IPrinter
{
    void Print(string message);
}
internal class ConsolePrinter : IPrinter
{
    public void Print(string message)
    {
        Console.WriteLine(message);
    }
}
internal class FilePrinter : IPrinter
{
    public void Print(string message)
    {
        File.WriteAllText("file.txt", message);
    }
}

Keyed Services in .NET 8

As we can see from the previous code snippet, the two classes are implementing a single interface, let’s see how can we register its dependency using a key.

We need to provide a string-based key in the Program.cs, but we can use enums as well instead of hard coding string values :

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddKeyedSingleton<IPrinter, ConsolePrinter>("Console");
builder.Services.AddKeyedSingleton<IPrinter, FilePrinter>("File");
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddKeyedSingleton<IPrinter, ConsolePrinter>(PrintTypes.Console);
builder.Services.AddKeyedSingleton<IPrinter, FilePrinter>(PrintTypes.File);
public enum PrintTypes
{
    Console,
    File
}

There are a couple of ways to inject the keyed services

  • Controller level & assign them

  • Method level specifically

[Route("[controller]")]
public class DemoController : ControllerBase
{

    public DemoController([FromKeyedServices(PrintTypes.Console)]
     IPrinter printer){ }
    public IActionResult Method1([FromKeyedServices(PrintTypes.File)] 
    IPrinter filePrinter)
    { }
}
[Route("[controller]")]
public class DemoController : ControllerBase
{

    [Inject(Key=PrintTypes.Console)]
    Public IPrinter _printer {get;set;}
    public DemoController([FromKeyedServices(PrintTypes.Console)]
     IPrinter printer)
    {
        _printer = printer;
    }
    
}

Currently, we have a limitation that this can not be applied directly to Minimal APIs yet.

How to achieve the same behavior in older versions of .NET?

We can achieve the same in older versions as well like this :

// Register services
builder.Services.AddSingleton<IPrinter, ConsolePrinter>();
builder.Services.AddSingleton<IPrinter, FilePrinter>();
[Route("[controller]")]
public class DemoController : ControllerBase
{
    private readonly IEnumerable<IPrinter> _printers;
    public DemoController(IEnumerable<IPrinter> printers)
    {
        _printers = printers;
    }
    [HttpGet]
    public IActionResult Method1()
    {
        // Find the ConsolePrinter instance from the collection of printers
        var consolePrinter = _printers.First(x => x.GetType() == typeof(ConsolePrinter));
        consolePrinter.Print("Hello from ConsolePrinter");
        return Ok("Message printed using ConsolePrinter.");
    }
   [HttpGet("file")]
    public IActionResult Method2()
    {
        // Find the FilePrinter instance from the collection of printers
        var filePrinter = _printers.First(x => x.GetType() == typeof(FilePrinter));
        filePrinter.Print("Hello from FilePrinter");
        return Ok("Message printed using FilePrinter.");
    }
}

This article was originally published at https://mwaseemzakir.substack.com/ on Jun 24, 2024 .

Whenever you're ready, there are 3 ways I can help you:

  1. Subscribe to my youtube channel : For in-depth tutorials, coding tips, and industry insights.
  2. Promote yourself to 9,000+ subscribers : By sponsoring this newsletter
  3. Patreon community : Get access to all of my blogs and articles at one place
Previous Next

Subscribe to Newsletter

Join 9,000 Software Engineers

Buy Me a Coffee

Enjoy my articles? Support me by buying a coffee!

Buy Me a Coffee

Muhammad Waseem

Resources
  • Books
  • Courses
Newsletter
  • Articles
  • Sponsorship
Books
  • 30 .NET Tips
  • 100 .NET Tips (Soon)
Author
  • About Us
  • Contact Us
Policy
  • Privacy Policy
  • Terms and Conditions
Interview
  • C# & .NET
  • Web API

Join my .NET newsletter and stay updated!

© 2025 Muhammad Waseem. All rights reserved.