[英]How to get Microsoft.Extensions.Logging<T> in console application using Serilog and AutoFac?
We have common BL classes in a ASP.NET Core application that get in the ctor:在 ASP.NET Core 应用程序中,我们有常见的 BL 类,它们会进入到构造函数中:
Microsoft.Extensions.Logging.ILogger<Foo>
In ASP.NET Core, the internal infrastructure of ASP.NET handles getting the ILogger via the LoggerFactory
.在 ASP.NET Core 中,ASP.NET 的内部基础结构处理通过
LoggerFactory
获取 ILogger。
We now want to reuse these BL classes in a console application (for async jobs), how do we setup AutoFac and Serilog to inject Microsoft.Extensions.Logging.ILogger<T>
in environment that LoggerFactory
doesn't exists?我们现在想在控制台应用程序中重用这些 BL 类(用于异步作业),我们如何设置AutoFac和 Serilog 以在
LoggerFactory
不存在的环境中注入Microsoft.Extensions.Logging.ILogger<T>
?
Microsoft.Extensions.Logging
(see source ) is not part of ASP.NET Core and can run independently of it. Microsoft.Extensions.Logging
(参见源代码)不是 ASP.NET Core 的一部分,可以独立于它运行。 All you need to do is to register the ILoggerFactory
and ILogger<>
interface.您需要做的就是注册
ILoggerFactory
和ILogger<>
接口。
The ILoggerFactory
is used by Logger<T>
to instantiate the actual logger. Logger<T>
使用ILoggerFactory
来实例化实际的记录器。
When using the Logging extension in console applications, its recommended still to use the IServiceCollection
, as this allows you to use the IServiceCollection
extension methods to register all packages which support this pattern.在控制台应用程序中使用 Logging 扩展时,建议仍然使用
IServiceCollection
,因为这允许您使用IServiceCollection
扩展方法来注册支持此模式的所有包。
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();
This is the recommended approach, as you won't have to think in detail which classes need to registered for libraries which have Microsoft.Extensions.DependencyInjection
integration support.这是推荐的方法,因为您不必详细考虑需要为具有
Microsoft.Extensions.DependencyInjection
集成支持的库注册哪些类。
But of course you can also register it manually, but when a change happens to the Microsoft.Extensions.Logging
library (new dependency added), you won't get it and first have to figure out or dig into the source code to find the error.但是当然你也可以手动注册它,但是当
Microsoft.Extensions.Logging
库(添加新的依赖项)发生变化时,你不会得到它,首先必须弄清楚或挖掘源代码才能找到错误。
builder.RegisterType<LoggerFactory>()
.As<ILoggerFactory>()
.SingleInstance();
builder.RegisterGeneric(typeof(Logger<>))
.As(typeof(ILogger<>))
.SingleInstance();
All that remains is to register the logger types after the container has been built or before your application starts:剩下的就是在容器构建之后或应用程序启动之前注册记录器类型:
var loggerFactory = container.Resolve<ILoggerFactory>();
loggerFactory.AddConsole()
.AddSerilog();
and in your services inject ILogger<MyService>
as usual.并像往常一样在您的服务中注入
ILogger<MyService>
。
I would recommend a slightly different approach if you want to register ir manually direct on Autofac:如果您想直接在 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
}
And this on you main startup code:这在你的主要启动代码上:
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.
In Console app Main method在控制台应用程序 Main 方法中
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>>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.