You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Serilog+Autofac下将ILogger<T>注入仅需ILogger的构造函数?

解决方案:使用Serilog + Autofac注入对应类的ILogger(而非ILogger)

核心思路

通过Autofac的自定义参数解析逻辑,在构造函数注入时自动将ILogger参数替换为当前类对应的ILogger<T>实例,避免重复编写泛型声明。本质是利用Autofac的注册拦截能力,根据目标类型动态生成对应日志实例。

所需依赖包

根据项目类型安装对应包:

  • ASP.NET Core 6:Autofac.Extensions.DependencyInjection、Serilog.AspNetCore、Serilog.Sinks.Console
  • .NET 6控制台应用:Autofac、Serilog、Serilog.Sinks.Console、Microsoft.Extensions.Logging

场景1:ASP.NET Core 6配置

在Program.cs中替换默认DI容器为Autofac,并添加日志注入规则:

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Serilog;

var builder = WebApplication.CreateBuilder(args);

// 1. 配置Serilog
builder.Host.UseSerilog((context, config) =>
{
    config.WriteTo.Console()
          .ReadFrom.Configuration(context.Configuration);
});

// 2. 替换为Autofac容器工厂
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

// 3. 配置Autofac注册规则
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    // 注册当前程序集下所有需要注入日志的类型
    containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly)
                   .AsSelf()
                   .WithParameter(
                       (pi, ctx) => pi.ParameterType == typeof(ILogger),
                       (pi, ctx) => ctx.Resolve<ILoggerFactory>().CreateLogger(pi.Member.DeclaringType)
                   );
});

// 其他服务注册...

var app = builder.Build();

// 中间件配置...

app.Run();

场景2:.NET 6控制台应用配置

手动构建Autofac容器并集成Serilog:

using Autofac;
using Microsoft.Extensions.Logging;
using Serilog;

// 1. 初始化Serilog
Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .CreateLogger();

// 2. 创建LoggerFactory,关联Serilog
var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddSerilog();
});

// 3. 构建Autofac容器
var containerBuilder = new ContainerBuilder();

// 注册LoggerFactory
containerBuilder.RegisterInstance(loggerFactory).As<ILoggerFactory>();

// 注册目标类型并添加日志注入规则
containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly)
               .AsSelf()
               .WithParameter(
                   (pi, ctx) => pi.ParameterType == typeof(ILogger),
                   (pi, ctx) => loggerFactory.CreateLogger(pi.Member.DeclaringType)
               );

using var container = containerBuilder.Build();

// 4. 验证注入
var myClass = container.Resolve<MyClass>();
myClass.DoSomething();

// 关闭Serilog
Log.CloseAndFlush();

验证代码(目标类)

按照期望的方式编写类,构造函数仅声明ILogger:

public class MyClass
{
    private readonly ILogger _logger;

    public MyClass(ILogger logger)
    {
        _logger = logger;
        _logger.LogInformation("MyClass构造函数初始化");
    }

    public void DoSomething()
    {
        _logger.LogInformation("执行DoSomething方法");
    }
}

关键说明

  1. 参数解析逻辑:WithParameter的两个委托分别用于判断参数是否为ILogger,以及动态创建对应类的ILogger实例(通过ILoggerFactory.CreateLogger传入当前类的类型)。
  2. 范围控制:如果不需要对所有类应用该规则,可以修改RegisterAssemblyTypes的过滤条件(比如指定命名空间、标记特定接口等)。
  3. Serilog集成:确保ILoggerFactory正确关联Serilog,这样生成的ILogger实例会使用Serilog作为底层日志实现。

内容的提问来源于stack exchange,提问作者Leyu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:57:18