Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何覆盖Autofac子作用域中的Serilog记录器?_C#_.net Core_Autofac_Serilog_Asp.net Core Hosted Services - Fatal编程技术网

C# 如何覆盖Autofac子作用域中的Serilog记录器?

C# 如何覆盖Autofac子作用域中的Serilog记录器?,c#,.net-core,autofac,serilog,asp.net-core-hosted-services,C#,.net Core,Autofac,Serilog,Asp.net Core Hosted Services,我有一个基本的.NET核心通用主机,它使用Serilog和Autofac 公共类程序 { 公共静态异步任务主(字符串[]args) { var配置=CreateConfiguration(args); Logger.Logger=新的LoggerConfiguration() .ReadFrom.Configuration(配置) .CreateLogger(); 尝试 { 日志信息(“启动主机…”); 等待新的HostBuilder() .UseServiceProviderFactory(新

我有一个基本的.NET核心通用主机,它使用Serilog和Autofac

公共类程序
{
公共静态异步任务主(字符串[]args)
{
var配置=CreateConfiguration(args);
Logger.Logger=新的LoggerConfiguration()
.ReadFrom.Configuration(配置)
.CreateLogger();
尝试
{
日志信息(“启动主机…”);
等待新的HostBuilder()
.UseServiceProviderFactory(新的AutofacServiceProviderFactory())
.ConfigureHostConfiguration(cb=>cb.AddConfiguration(配置))
.ConfigureServices((ctx、sc)=>{
sc.AddLogging(lb=>lb.AddSerilog());
})
.ConfigureContainer(cb=>{
注册表模块(新的AppModule());
})
.RunConsoleAsync();
}
捕获(例外情况除外){
Log.Fatal(例如,“主机意外终止”);
}
最后{
Log.CloseAndFlush();
}
}
专用静态IConfiguration CreateConfiguration(IReadOnlyCollection参数)
{
返回新的ConfigurationBuilder()
.AddJsonFile(“appsettings.json”,false,true)
.AddUserSecrets(true)
.AddCommandLine(args.ToArray())
.Build();
}
}
AppModule
是一个Autofac模块,我在其中注册了
IHostedService

内部类AppModule:模块
{
受保护的覆盖无效负载(ContainerBuilder builder)
{
建筑商登记(
ctx=>{
var c=ctx.Resolve();
返回新的AutofacHostedServiceScopeOwner(
()=>c.Resolve()
.BeginLifetimeScope(b=>b.Register(x=>Log.Logger.ForContext(“名称”、“值”)).As(),
scope=>newmessageprocessingservice(
scope.Resolve()
)
);
}
)
.As();
}
}
这部分看起来很复杂,但我试图完成的是在Autofac子作用域中运行
MessageProcessingService
(一个
IHostedService
实现),这样我就可以用一些特定于上下文的信息覆盖整个
MessageProcessingService
图中已解析的记录器。将有多个
MessageProcessingService
实例,每个实例都需要一个具有唯一上下文的记录器,以便我可以关联日志输出

我使用
AutofacHostedServiceScopeOwner
在子作用域中包装
MessageProcessingService
。也许有更好的方法,但这是我能想到的最好的方法

公共类AutofacHostedServiceScopeOwner:IHostedService,IDisposable
{
私有只读函数;
私有只读函数服务工厂;
专用ILifetimeScope\u currentScope;
私人IHostedService(u hostedService);;
公共AutofacHostedServiceScopeOwner(Func scopeFactory、Func serviceFactory){
_scopeFactory=scopeFactory;
_服务工厂=服务工厂;
}
公共异步任务StartAsync(CancellationToken CancellationToken){
_currentScope=_scopeFactory();
_hostedService=\u serviceFactory(\u currentScope);
wait_hostedService.StartAsync(取消令牌);
}
公共异步任务StopAsync(CancellationToken CancellationToken){
if(_hostedService!=null)
wait_hostedService.stopsync(cancellationToken);
_currentScope?.Dispose();
}
公共空间处置(){
_currentScope?.Dispose();
}
}
除了解析的记录器不包含预期的上下文属性外,所有这些都正常工作。这让我觉得我的覆盖逻辑是错误的,但我不确定还有什么可以尝试

c.Resolve<ILifetimeScope>()
    .BeginLifetimeScope(
        b => b.Register(x => Log.Logger.ForContext("name", "value")).As<Serilog.ILogger>()
    )

我在头撞了几个小时后才明白这一点

builder.Register(
ctx=>{
var c=ctx.Resolve();
返回新的AutofacHostedServiceScopeOwner(
()=>c.Resolve()
.BeginLifetimeScope(
b=>{
b、 RegisterGeneric(typeof(Logger)).As(typeof(ILogger));
b、 登记册(
x=>new SeriologgerFactory(
Log.Logger.ForContext(“名称”、“值”)
)
)
.As()
.InstancePerLifetimeScope();
}
),
scope=>newmessageprocessingservice(
scope.Resolve()
)
);
}
)
.As();
之所以这样做,是因为在
Program.cs
中,记录器配置调用
sc.AddLogging(lb=>lb.AddSerilog())
ILogger
ILoggerFactory
注册为盖下的单例。
lb.AddSerilog()
调用注册了一个Serilog提供程序,该提供程序由
ILoggerFactory
使用,但我无法找到任何方法专门覆盖该提供程序,因此我将其全部替换


希望这能帮助一些人。

更换整个记录器工厂似乎很昂贵。“你考虑过吗?”Travigig我考虑过了,但不确定如何把它应用到一个范围内。我还尝试了LogContext.PushProperty,但也没有找到答案。
{
  "Serilog": {
    "Enrich": [ "FromLogContext" ],
    "MinimumLevel": "Debug",
    "WriteTo": [
      {
        "Name": "Console"        
      }
    ]
  }
}