Created
December 23, 2024 20:46
-
-
Save gusarov/d43c7b6e2ae32d5ee23cb651b41d5374 to your computer and use it in GitHub Desktop.
Prevent duplicated service registration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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