For .NET Generic Host it is possible to register multiple implementations of same service interface. When materializing that service the last added is obtained (that is correct even for multiple implementations registered with same key):
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
namespace IHostTest;
internal class Program
{
static async Task Main()
{
var hostBuilder = Host.CreateDefaultBuilder().ConfigureServices(services =>
{
services.AddSingleton<ISomeService, SomeService1>();
services.AddSingleton<ISomeService, SomeService2>();
services.AddKeyedSingleton<ISomeService, SomeService1>("key");
services.AddKeyedSingleton<ISomeService, SomeService2>("key");
});
var host = hostBuilder.Build();
//will get SomeService2 here
var service = host.Services.GetRequiredService<ISomeService>();
//will also get SomeService2 here
var keyedService = host.Services.GetRequiredKeyedService<ISomeService>("key");
await host.RunAsync();
}
}
internal interface ISomeService
{ }
internal class SomeService1 : ISomeService
{ }
internal class SomeService2 : ISomeService
{ }
Is there any way to forbid multiple service implementations? I need to get an exception when building my host in that case. Or detecting such situation via unit tests is the only option?
.GetServiceEnsureSingleImplementation<ISomeService>()where I should place this check before actually calling.GetRequiredService<ISomeService>()? It looks like an overkill to check this every time I need any service - checking whole container once in a unit-test looks be better from my point of view.last added is obtainedthat's not correct, if you use an array egGetRequiredService<ISomeService[]>()you'll get all implementationsIServiceCollectionto the concreteServiceCollectionand iterate over its contents