Skip to content

Instantly share code, notes, and snippets.

@gusarov
Created December 23, 2024 20:46
Show Gist options
  • Save gusarov/d43c7b6e2ae32d5ee23cb651b41d5374 to your computer and use it in GitHub Desktop.
Save gusarov/d43c7b6e2ae32d5ee23cb651b41d5374 to your computer and use it in GitHub Desktop.
Prevent duplicated service registration
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
namespace CompanyName;
internal class Program
{
private static void Main(string[] args)
{
var appBuidler = Host.CreateApplicationBuilder();
appBuidler.ConfigureContainer(new ConstrainedServiceProviderFactory());
appBuidler.Services.AddSingleton<IService, Serivce1>();
appBuidler.Services.AddSingleton<IService, Serivce2>();
var app = appBuidler.Build();
app.Run();
}
}
interface IService
{
}
class Serivce1 : IService
{
}
class Serivce2 : IService
{
}
internal class ConstrainedServiceProviderFactory : IServiceProviderFactory<ConstrainedServiceProviderFactory.ContainerBuilder>
{
internal class ContainerBuilder
{
public ContainerBuilder(IServiceCollection services)
{
Services = services;
}
public IServiceCollection Services { get; }
}
public ContainerBuilder CreateBuilder(IServiceCollection services)
{
return new ContainerBuilder(services);
}
public IServiceProvider CreateServiceProvider(ContainerBuilder containerBuilder)
{
CheckConstraints(containerBuilder.Services);
return containerBuilder.Services.BuildServiceProvider();
}
private void CheckConstraints(IServiceCollection services)
{
/*
var lookups = services.Where(x => x.ServiceType.Namespace == "CompanyName").ToLookup(x => (x.ServiceType, x.ServiceKey));
foreach (var service in lookups.Where(x => x.Count() > 1))
{
foreach (var item in service)
{
Console.WriteLine($"{item.ServiceType.Name} + {item.ServiceKey}");
}
}
*/
var registrations = new Dictionary<Type, ServiceDescriptor>();
foreach (var item in services.Where(x => x.ServiceType.Namespace == "CompanyName"))
{
if (!registrations.TryAdd(item.ServiceType, item))
{
var existing = registrations[item.ServiceType];
throw new Exception($"Can not add Service {item.ServiceType.Name} implemented as {item.ImplementationType?.Name} because it is already registered as {existing.ImplementationType?.Name}");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment