如何使用 Serilog 和 AutoFac 在控制台应用程序中获取 Microsoft.Extensions.Logging<T>?

Posted

技术标签:

【中文标题】如何使用 Serilog 和 AutoFac 在控制台应用程序中获取 Microsoft.Extensions.Logging<T>?【英文标题】:How to get Microsoft.Extensions.Logging<T> in console application using Serilog and AutoFac? 【发布时间】:2017-05-15 20:24:27 【问题描述】:

我们在 ASP.NET Core 应用程序中有常见的 BL 类,它们可以进入 ctor:

Microsoft.Extensions.Logging.ILogger&lt;Foo&gt;

在 ASP.NET Core 中,ASP.NET 的内部基础结构通过LoggerFactory 处理获取 ILogger。

我们现在想在控制台应用程序中重用这些 BL 类(用于异步作业),我们如何设置 AutoFac 和 Serilog 在 LoggerFactory 不存在的环境中注入 Microsoft.Extensions.Logging.ILogger&lt;T&gt; ?

【问题讨论】:

“LoggerFactory 不存在的环境”是什么意思? LoggerFactory 不是 ASP.NET Core 的一部分,它是 Microsoft.Extensions.Logging 包的一部分,请参阅github.com/aspnet/Logging/blob/dev/src/… 【参考方案1】:

Microsoft.Extensions.Logging(请参阅source)不是 ASP.NET Core 的一部分,可以独立运行。只需注册ILoggerFactoryILogger&lt;&gt;接口即可。

ILoggerFactoryis used byLogger&lt;T&gt; 用于实例化实际的记录器。

在控制台应用程序中使用 Logging 扩展时,建议仍使用IServiceCollection,因为这允许您使用IServiceCollection extension methods 注册所有支持此模式的包。

var services = new ServiceCollection();
services.AddLogging();

// Initialize Autofac
var builder = new ContainerBuilder();
// Use the Populate method to register services which were registered
// to IServiceCollection
builder.Populate(services);

// Build the final container
IContainer container = builder.Build();

这是推荐的方法,因为您不必详细考虑哪些类需要为具有 Microsoft.Extensions.DependencyInjection 集成支持的库注册。

当然你也可以手动注册,但是当Microsoft.Extensions.Logging库发生变化(添加了新的依赖),你不会得到它,首先必须弄清楚或挖掘into the source code才能找到错误。

builder.RegisterType<LoggerFactory>()
    .As<ILoggerFactory>()
    .SingleInstance();
builder.RegisterGeneric(typeof(Logger<>))
    .As(typeof(ILogger<>))
    .SingleInstance();

剩下的就是在构建容器之后或应用程序启动之前注册记录器类型:

var loggerFactory = container.Resolve<ILoggerFactory>();
loggerFactory.AddConsole()
    .AddSerilog();

并像往常一样在您的服务中注入ILogger&lt;MyService&gt;

【讨论】:

通用记录器需要使用Autofac注册builder.RegisterGeneric(typeof(Logger&lt;&gt;)).As(typeof(ILogger&lt;&gt;)).SingleInstance(); 这对我不起作用,直到我添加了上面 Ruskin 评论的行。谢谢! @RyanOC:那么您可能没有调用services.AddLogging();,因为那是注册Logger&lt;T&gt;/ILogger&lt;T&gt; 实例的那个 @Tseng,你是对的。在花了更多时间之后,我能够单独使用您的答案。谢谢! 我编辑了答案以获得正确的代码。感谢@Ruskin 的更正。【参考方案2】:

如果您想直接在 Autofac 上手动注册 ir,我会推荐一种稍微不同的方法:

private static void ConfigureLogging(ILoggingBuilder log)

    log.ClearProviders();
    log.SetMinimumLevel(LogLevel.Error);
    log.AddConsole();


private static void ConfigureContainer(ContainerBuilder builder)

    builder.Register(handler => LoggerFactory.Create(ConfigureLogging))
        .As<ILoggerFactory>()
        .SingleInstance()
        .AutoActivate();

    builder.RegisterGeneric(typeof(Logger<>))
        .As(typeof(ILogger<>))
        .SingleInstance();
    // other registrations

这是你的主要启动代码:

var containerBuilder = new ContainerBuilder();
ConfigureContainer(containerBuilder);

var container = containerBuilder.Build();
var serviceProvider = new AutofacServiceProvider(container);
// you can use either the built container or set the serviceProvider onto the library you are using.

【讨论】:

【参考方案3】:

在控制台应用主方法中

var builder = new ConfigurationBuilder()
             .SetBasePath(Directory.GetCurrentDirectory())
             .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
             .AddEnvironmentVariables();
        IConfigurationRoot configuration = builder.Build();

        var serviceProvider = new ServiceCollection()
                .AddDbContext<MyDbContext>(optionns => optionns.UseSqlServer(configuration.GetConnectionString("connectionString")))
                .AddSingleton(typeof(ILogger<>), typeof(Logger<>))
                .AddLogging() 
                .BuildServiceProvider();

        MyDbContext _context = serviceProvider.GetService<MyDbContext>();
        var _logger = serviceProvider.GetService<ILogger<YourClass>>();

【讨论】:

答案不使用 AutoFac 感谢@ArunSolanki - 很有帮助,因为我登陆这里只是为了寻找“将日志记录添加到 .net 核心控制台”

以上是关于如何使用 Serilog 和 AutoFac 在控制台应用程序中获取 Microsoft.Extensions.Logging<T>?的主要内容,如果未能解决你的问题,请参考以下文章

web-api启动时如何注入和使用Serilog(Ilogger)

如何在 appsettings.json 中使用多个单独的记录器 Serilog 文件

如何使用 Serilog 以有效的 json 格式记录复杂对象?

如何在 .Net Framework 中使用 Serilog 为每个 API 创建日志文件?

如何使用 serilog 在 kibana 中通过身份验证将日志设置为 ELK

如何从 Serilog 中排除特定的异常类型?