#asp.net-core #.net-core #asp.net-core-3.1 #.net-core-3.1
#asp.net-core #.net-core #asp.net-core-3.1 #.net-core-3.1
Вопрос:
Я пытаюсь создать «реестр», чтобы просто создать новый класс, реализующий IServiceCollectionInitializer или IApplicationBuilderInitializer, позволяющий его загружать. Вместо того, чтобы иметь гигантский класс запуска, реестр добавит их автоматически.
Моя проблема в том, что я не знаю, как заставить приложение либо использовать новый конструктор приложений, либо извлекать тот, который задан автоматически, не получая его при запуске.
public class ServiceCollectionInitializerRegistry
{
private readonly IList<IServiceCollectionInitializer> _serviceCollectionInitializers;
private readonly IServiceCollection _serviceCollection;
private readonly IServiceProvider _serviceProvider;
public ServiceCollectionInitializerRegistry(IServiceCollection serviceCollection)
{
_serviceCollectionInitializers = new List<IServiceCollectionInitializer>();
_serviceCollection = serviceCollection;
_serviceProvider = serviceCollection.BuildServiceProvider();
}
public ServiceCollectionInitializerRegistry WithInitializers(
params IServiceCollectionInitializer[] initializers)
{
if (!initializers.Any())
{
return this;
}
foreach (var initializer in initializers)
{
_serviceCollectionInitializers.Add(initializer);
}
return this;
}
public ServiceCollectionInitializerRegistry WithAssemblyInitializers()
{
var assembly = Assembly.GetEntryAssembly();
var initializerTypes =
assembly.GetTypes()
.Where(type => typeof(IServiceCollectionInitializer).IsAssignableFrom(type));
if (!initializerTypes.Any())
{
return this;
}
foreach (var type in initializerTypes)
{
_serviceCollectionInitializers.Add((IServiceCollectionInitializer)Activator.CreateInstance(type));
}
return this;
}
public void Build()
{
var configuration = _serviceProvider.GetRequiredService<IConfiguration>();
foreach (var serviceCollectionInitializer in _serviceCollectionInitializers)
{
var logger = _serviceProvider.GetRequiredService<ILoggerProvider>()
.CreateLogger(serviceCollectionInitializer.GetType().AssemblyQualifiedName);
serviceCollectionInitializer
.Initialize(
configuration,
_serviceCollection, logger);
}
}
}
public class ExceptionHandlingInitializer : IServiceCollectionInitializer, IApplicationBuilderInitializer
{
public void Initialize(IConfiguration configuration, IServiceCollection services, ILogger logger)
{
services.AddSingleton<IExceptionMapper, ExceptionMapper>();
services.AddSingleton<IExceptionHandler, ExceptionHandler>();
}
public void Initialize(IConfiguration configuration, IApplicationBuilder builder, ILoggerFactory loggerFactory)
{
builder.UseExceptionHandlerMiddleware();
}
}
Комментарии:
1. Какова цель этого, т.Е. Чего вы пытаетесь достичь? Возможно, есть способ решить эту проблему по-другому и сохранить ваш класс запуска тонким и аккуратным, не прибегая к этому маршруту.