Keyed Services in the IServiceProvider in .NET 8 preview 7

07/08/2023

The .NET 8 preview 7 will bring another exciting feature some of you probably awaiting for a long time: Keyed services.

Example

using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<BigCacheConsumer>();
builder.Services.Addsingleton<SmallCacheConsumer>();

builder.Services.AddKeyedSingleton<IMemoryCache, BigCache>(“big“);
builder.Services.AddKeyedSingleton<IMemoryCache, SmallCache>("small“);

var app = builder.Build();

app.MapGet(“/big", (BigCacheConsumer data) => data.GetData());
app.MapGet(“/small", (SmallCacheConsumer data) => data.GetData());

app.Run();

class BigCacheConsumer([FromKeyedServices("big“)] IMemoryCache cache)
{
    public object? GetData() => cache.Get("data");
}

class SmallCacheConsumer(IServiceProvider keyedServiceProvider)
{
    public object? GetData() => keyedServiceProvider.GetRequiredKeyedService<IMemoryCache>("big");
}

The addition of new overloads like AddKeyedSingleton or AddKeyedScoped allow to pass in a named (keyed) service that can then be consumed with a new attribute in the dependent service.

Also, as shown in the SmallCacheConsumer, there is the option to retrieve them at runtime:

var keyedService = keyedServiceProvider.GetRequiredKeyedService<IService>("key");

So why would you need keyed services in the first place? There could be multiple scenarios, like: Multitenancy, feature toggles, or A/B testing.

6
An error has occurred. This application may no longer respond until reloaded. Reload x