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

如何实现ILoggerFactory?自定义工厂配置与调用方法咨询

按名称指定日志提供程序的实现方案

1. 实现自定义ILoggerFactory:MyFactory

需要实现ILoggerFactory接口,同时维护日志提供程序与名称的映射关系,核心是根据指定名称找到对应Provider创建日志实例。

using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using System.Linq;

public class MyFactory : ILoggerFactory
{
    private readonly ConcurrentDictionary<string, ILoggerProvider> _providerMap = new();
    private bool _disposed = false;

    // 构造函数注入所有已注册的日志提供程序,并绑定名称
    public MyFactory(IEnumerable<ILoggerProvider> providers)
    {
        foreach (var provider in providers)
        {
            // 按Provider类型关联名称,也可以根据Provider自定义的Name属性绑定
            var providerName = provider.GetType().Name;
            _providerMap.TryAdd(providerName, provider);
        }
    }

    // 实现接口要求的默认CreateLogger方法
    public ILogger CreateLogger(string categoryName)
    {
        // 返回第一个注册的Provider实例,或根据业务需求调整默认逻辑
        return _providerMap.Values.First().CreateLogger(categoryName);
    }

    // 自定义泛型方法:按类型分类+指定Provider名称创建日志
    public ILogger<T> CreateLogger<T>(string providerName)
    {
        if (!_providerMap.TryGetValue(providerName, out var targetProvider))
            throw new ArgumentException($"未找到名为 {providerName} 的日志提供程序");
        
        return new LoggerWrapper<T>(targetProvider.CreateLogger(typeof(T).FullName));
    }

    public void AddProvider(ILoggerProvider provider)
    {
        var providerName = provider.GetType().Name;
        _providerMap.TryAdd(providerName, provider);
    }

    public void Dispose()
    {
        if (_disposed) return;
        
        foreach (var provider in _providerMap.Values)
            provider.Dispose();
        
        _disposed = true;
    }

    // 泛型日志包装类,适配ILogger<T>接口
    private class LoggerWrapper<T> : ILogger<T>
    {
        private readonly ILogger _innerLogger;

        public LoggerWrapper(ILogger innerLogger)
        {
            _innerLogger = innerLogger;
        }

        public IDisposable BeginScope<TState>(TState state) => _innerLogger.BeginScope(state);
        public bool IsEnabled(LogLevel logLevel) => _innerLogger.IsEnabled(logLevel);
        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
            => _innerLogger.Log(logLevel, eventId, state, exception, formatter);
    }
}

如果不想在MyFactory内定义泛型方法,也可以通过扩展方法实现:

public static class LoggerFactoryExtensions
{
    public static ILogger<T> CreateLogger<T>(this ILoggerFactory factory, string providerName)
    {
        if (factory is not MyFactory myFactory)
            throw new InvalidOperationException("当前LoggerFactory不是自定义的MyFactory实例");
        
        return myFactory.CreateLogger<T>(providerName);
    }
}

2. 在Program.cs中加载MyFactory

替换默认的ILoggerFactory注册,确保自定义工厂能获取到已注册的日志提供程序:

var builder = WebApplication.CreateBuilder(args);

// 注册日志提供程序(保留原有逻辑)
builder.Services.AddLogging(loggingBuilder =>
{
    loggingBuilder.ClearProviders();
    loggingBuilder.AddProvider(new LoggerProvider1());
    loggingBuilder.AddProvider(new LoggerProvider2());
});

// 替换默认LoggerFactory为自定义MyFactory
builder.Services.AddSingleton<ILoggerFactory, MyFactory>();

// 其他服务注册逻辑...
var app = builder.Build();

// 应用启动逻辑...
app.Run();

3. 调用ILoggerFactory获取指定Provider的日志实例

在需要的类中注入ILoggerFactory,直接调用自定义方法获取对应Provider的日志实例:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _loggerFromProvider1;
    private readonly ILogger<HomeController> _loggerFromProvider2;

    public HomeController(ILoggerFactory factory)
    {
        // 按名称指定Provider获取日志实例
        _loggerFromProvider1 = factory.CreateLogger<HomeController>("LoggerProvider1");
        _loggerFromProvider2 = factory.CreateLogger<HomeController>("LoggerProvider2");
    }

    public IActionResult Index()
    {
        _loggerFromProvider1.LogInformation("通过LoggerProvider1记录的日志");
        _loggerFromProvider2.LogInformation("通过LoggerProvider2记录的日志");
        return View();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:22:48