如何解决IHostBuilder.ConfigureServices 引导程序中的简单注入器 LoggerFactory
我将 Simple Injector 与通用主机 nuget 包一起使用,一切都很好,只是我在注册顺序上遇到了障碍。
我有一个返回两个接口 IMessagePublisher
和 IMessageSubscriber
的构建器类,这个构建器类也需要一个 ILoggerFactory
。
我无法使用 ILoggerFactory
,因为它尚未配置,并且无法调用 container.GetInstance<ILoggerFactory>
,因为在调用代码时容器仍在使用注册进行引导。
我的主要主持人在这里:
var host = CreateHostBuilder(args)
.UseSerilog((hostContext,loggerConfiguration) =>
{
var setting = hostContext.Configuration
.GetSection(Settings.Name).GetAndAssert<Settings>();
if (setting.IsDebug == true)
loggerConfiguration.MinimumLevel.Debug();
else
loggerConfiguration.MinimumLevel.information();
loggerConfiguration
.MinimumLevel.Override("Microsoft",LogEventLevel.Warning)
.Enrich.FromLogContext()
.Writeto.Console()
.Writeto.File("logging.log");
})
.Build()
.UseSimpleInjector(container);
我的 CreateHostBuilder 如下(我的问题出在 builder.Create
方法中):
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host
.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostContext,builder) =>
{
if (hostContext.HostingEnvironment.IsDevelopment())
{
builder.AddUserSecrets<Program>();
}
})
.ConfigureServices((hostContext,services) =>
{
services.AddSimpleInjector(container,options =>
{
options.AddHostedService<Worker>();
options.AddLogging();
var mqttSettings = hostContext
.Configuration
.GetSection(MqttSettings.Name)
.GetAndAssert<MqttSettings>();
var builder = new MqttMessageBusBuilder(mqttSettings);
builder.Create(
new[] { new MessagePackSerializer() },new IdentifyUsingTransportHeaders(),/* below is not allowed */
container.GetInstance<ILoggerFactory>,// i also dont kNow where to get IloggerFactory if not yet configured
out var messagePublisher,out var messageSubscriber,mqttSettings.isDebug);
container.RegisterInstance(messagePublisher);
container.RegisterInstance(messageSubscriber);
});
});
}
我无法使用单例并将实例化推迟到需要时,因为我需要构建器返回 IMessagePublisher
和 IMessageSubscriber
实例。
否则我会在 container.GetInstance<ILoggerFactory>()
有效的情况下使用以下内容:
// register factory to create polygonWebsocket
container.RegisterSingleton( () => {
var settings = container.GetInstance<Settings>();
var secrets = container.GetInstance<Secrets>();
return new polygonWebsocket(
secrets.polygonIoApiKey,settings.polygonWebSocketUrl,settings.polygonReconnectTimeout,container.GetInstance<ILoggerFactory>()
});
如何在 MqttMessageBusBuilder.Create
引导期间将 ILoggerFactory 注入我的 CreateHostBuilder
方法?
解决方法
这个问题与 Simple Injector 无关,因为 ILoggerFactory
来自 IServiceCollection
及其最后的 IServiceProvider
,这是一个先有鸡还是先有蛋的困境。您想在 ILoggerFactory
期间将 MqttMessageBusBuilder.Create
提供给 ConfigureServices
,而 ILoggerFactory
只能在可用时从 IServiceProvider
解析,这是在稍后的阶段。
据我所知,您可以做三件事:
- 从
ILoggerFactory
中拉入IServiceCollection
,因为此时的注册已经存在于IServiceCollection
中。 - 在
ConfigureServices
之后(即在Configure
内)推迟注册您的消息接口 - 现在进行注册,但使用延迟初始化,以便在解析消息接口时构建。
示例 1:
.ConfigureServices((hostContext,services) =>
{
var factory = (ILoggerFactory)services
.Last(s => s.ServiceType == typeof(ILoggerFactory))
.ImplementationInstance;
services.AddSimpleInjector(container,options =>
{
...
var builder = new MqttMessageBusBuilder(mqttSettings);
builder.Create(
new[] { new MessagePackSerializer() },new IdentifyUsingTransportHeaders(),factory,out var messagePublisher,out var messageSubscriber,mqttSettings.isDebug);
container.RegisterInstance(messagePublisher);
container.RegisterInstance(messageSubscriber);
});
});
示例 2:
var host =
CreateHostBuilder(args)
.UseSerilog((hostContext,loggerConfiguration) =>
{
...
})
.Build()
.UseSimpleInjector(container);
var factory = host.Services.GetRequiredInstance<ILoggerFactory>();
var mqttSettings = hostContext
.Configuration
.GetSection(MqttSettings.Name)
.GetAndAssert<MqttSettings>();
var builder = new MqttMessageBusBuilder(mqttSettings);
builder.Create(
new[] { new MessagePackSerializer() },mqttSettings.isDebug);
container.RegisterInstance(messagePublisher);
container.RegisterInstance(messageSubscriber);
return host;
示例 3:
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host
.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostContext,builder) =>
{
if (hostContext.HostingEnvironment.IsDevelopment())
{
builder.AddUserSecrets<Program>();
}
})
.ConfigureServices((hostContext,services) =>
{
services.AddSimpleInjector(container,options =>
{
...
var lazy = new Lazy<(
IMessagePublisher Publisher,IMessageSubcriber Subscriber)>(() =>
{
var builder = new MqttMessageBusBuilder(mqttSettings);
builder.Create(
new[] { new MessagePackSerializer() },container.GetInstance<ILoggerFactory>(),mqttSettings.isDebug);
return (messagePublisher,messageSubscriber);
});
container.RegisterSingleton(() => lazy.Value.Publisher);
container.RegisterInstance(() => lazy.Value.Subscriber);
});
});
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。