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

时间:2017-01-01 10:29:29

标签: c# dependency-injection asp.net-core autofac serilog

我们在ASP.NET核心应用程序中有共同的BL类,它们位于ctor:

Microsoft.Extensions.Logging.ILogger<Foo>

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

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

3 个答案:

答案 0 :(得分:24)

Microsoft.Extensions.Logging(请参阅source)不是ASP.NET Core的一部分,可以独立运行。您需要做的就是注册ILoggerFactoryILogger<>接口。

ILoggerFactory is used by Logger<T>来实例化实际的记录器。

在控制台应用程序中使用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库发生变化(添加了新的依赖项)时,你不会得到它,首先要弄清楚或挖掘{{ 3}}找到错误。

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

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

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

并在您的服务中像往常一样注入ILogger<MyService>

答案 1 :(得分: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.

答案 2 :(得分:0)

在控制台应用程序的“主要”方法中

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>>();