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

如何用Autofac注册微软ILogger并自动注入对应类型的ILogger<T>

你的反射实现完全没必要

你反射调用的Operation、ServiceType都属于Autofac的内部非公开API,存在版本升级后内部结构变更导致代码失效的风险,可维护性极差。


最优实现方案

Autofac原生提供了参数匹配的能力,不需要任何私有API反射即可实现需求,分两步即可:

1. 注入对应消费类类型的ILogger

直接注册全局的ResolvedParameter,匹配所有构造函数中的ILogger参数,自动为其创建对应消费类类型的日志实例:

// 先注册ILoggerFactory,直接使用微软扩展的AddLogging即可
builder.AddLogging();

// 全局匹配所有ILogger类型的构造参数,自动创建对应类型的Logger
builder.RegisterInstance(new ResolvedParameter(
    // 匹配条件:参数类型为ILogger
    (parameterInfo, context) => parameterInfo.ParameterType == typeof(ILogger),
    // 生成实例:用参数所属的类作为类别创建Logger
    (parameterInfo, context) => 
        context.Resolve<ILoggerFactory>().CreateLogger(parameterInfo.Member.DeclaringType)
)).AsSelf();

这个方案不需要你自定义LogManager<T>,也不需要修改现有类的构造逻辑,MyFactory里注入的ILogger自动就是ILogger<MyFactory>的等效实例,SourceContext会自动设置为MyFactory的完整类名,完全符合你的需求。

2. 携带工作单元通用属性

不建议在Logger创建阶段附加通用Scope属性,正确的做法是在工作单元的入口统一添加:

// 例如在接口请求、任务启动的入口处
public class WorkUnitHandler
{
    private readonly ILogger _logger;
    public WorkUnitHandler(ILogger logger) => _logger = logger;

    public async Task Handle(WorkUnit workUnit)
    {
        // 统一附加当前工作单元的通用属性
        using var scope = _logger.BeginScope(new Dictionary<string, object>
        {
            {"OrderNumber", workUnit.OrderNumber},
            {"User", workUnit.User}
        });

        // 后续工作单元内所有日志都会自动带上上述Scope属性
        // 包括链路中所有类打印的日志
    }
}

这种实现符合.NET日志的设计规范,Scope的生命周期和工作单元绑定,不会出现属性串用的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:06:03