TLDR; this is no longer the case. See this working example.
using FromKeyed;
using FromKeyed.Interfaces;
using FromKeyed.Services;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();
builder.Services.AddKeyedSingleton<IService, OneKeyedService>("keyed");
builder.Services.AddSingleton<IService, Service>();
var host = builder.Build();
host.Run();
Code language: C# (cs)
namespace FromKeyed.Interfaces;
public interface IService
{
string Name { get; }
}
Code language: C# (cs)
using FromKeyed.Interfaces;
namespace FromKeyed.Services;
public class Service : IService
{
public string Name => nameof(Service);
}
public class OneKeyedService : IService
{
public string Name => nameof(OneKeyedService);
}
Code language: C# (cs)
using FromKeyed.Interfaces;
namespace FromKeyed;
public class Worker(
[FromKeyedServices("keyed")] IService keyedService,
IService service,
ILogger<Worker> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
logger.LogInformation("keyedService says {KeyedService}, service says {Service}", keyedService.Name, service.Name);
await Task.Delay(1000, stoppingToken);
}
}
}
Code language: C# (cs)
Gives the following output
~/Projects/FromKeyed » dotnet run blomqvist@Niklas-MBP
Building...
info: FromKeyed.Worker[0]
keyedService says KeyedService, service says Service
Code language: Shell Session (shell)
Obsolete post below
Today I discovered that, when using NET 8 and a service with primary constructor, the FromKeyedServicesAttribute does nothing (I assume). Perhaps the attribute is magically removed when the code is compiled.
I guess that
public class PaymentService(
[FromKeyedServices("defaultPaymentProvider")]
IPaymentProvider defaultPaymentProvider
) : IPaymentService
{ }
Code language: C# (cs)
is changed to
public class PaymentService : IPaymentService
{
public PaymentService(IPaymentProvider defaultPaymentProvider)
{ }
}
Code language: C# (cs)
on compile (note the missing attribute!)
Changing from primary constructor to an ordinary constructor with no other change made the code work as intended.