C# 将NLog连接并注入.NET核心控制台应用程序
我创建了一个consumer/job,我将在用C#编写的Linux上作为进程运行 该进程将:C# 将NLog连接并注入.NET核心控制台应用程序,c#,.net-core,nlog,C#,.net Core,Nlog,我创建了一个consumer/job,我将在用C#编写的Linux上作为进程运行 该进程将: 从RabbitMQ读取消息 对数据库进行更改 记录任何错误 NLog上关于.NET Core的所有文档都在ASP.NET Core上。当我尝试获取ILogger实现时,它返回null 以下是接线和使用说明: static void ConfigureServices() { 字符串environment=environment.GetEnvironmentVariable(“ASPNETCORE_环境”
ILogger
实现时,它返回null
以下是接线和使用说明:
static void ConfigureServices()
{
字符串environment=environment.GetEnvironmentVariable(“ASPNETCORE_环境”);
var builder=new ConfigurationBuilder()
.SetBasePath(Path.Combine(AppContext.BaseDirectory))
.AddJsonFile(“appsettings.json”,可选:true,重载更改:true)
.AddJsonFile($“appsettings.{environment}.json”,可选:true);
var services=newservicecolection();
Configuration=builder.Build();
[...]
services.AddLogging();
ServiceProvider=services.BuildServiceProvider();
var loggerFactory=ServiceProvider.GetService();
loggerFactory.AddNLog();
}
静态void Main(字符串[]参数)
{
配置服务();
var logger=ServiceProvider.GetService();
调试(“日志”);
[...]
}
不要与环境变量相混淆ASPNETCORE_environment
;它仅用于确定要使用的appsettings.json
我的代码基于此
最后,这些是我目前安装的软件包
一个完整的.NET Core 1控制台应用程序中NLog的最低限度示例(基于存储库):
var services=newservicecolection();
services.AddLogging();
var provider=services.BuildServiceProvider();
var factory=provider.GetService();
factory.AddNLog();
factory.ConfigureNLog(“nlog.config”);
var logger=provider.GetService();
logger.LogCritical(“hello nlog”);
参考资料:
<ItemGroup>
<PackageReference Include="NLog.Extensions.Logging" Version="1.0.0-rtm-beta5" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.2" />
</ItemGroup>
nlog.config:
我的解决方案是使用一个使用Console.Writeline的适配器模式,直到一个更健全的NLog版本可用为止
using System;
public static class Log
{
public static void Write(string message)
{
Console.WriteLine($"{DateTime.Now}: {message}");
}
}
在DotnetCore2中,您现在可以使用start-up类,并稍微清理代码,使其看起来更像web类 作为奖励,您可以使用ConsoleApp在DI容器内启动应用程序 Program.cs
static void Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
Startup startup = new Startup();
startup.ConfigureServices(services);
IServiceProvider serviceProvider = services.BuildServiceProvider();
// entry to run app
serviceProvider.GetService<ConsoleApp>().Run();
}
解析
Microsoft.Extensions.Logging.ILogger
而不是NLog.ILogger
@IlyaChumakov不会给我msft日志并通过msft日志路由我的所有日志吗?实际上,我刚刚测试了这个,并且logger
仍然为空。我的错,我的意思是ILogger
。是的,你收到了一个通用的msft日志。一般来说,这是好的,因为您的代码不依赖于具体的记录器实现。您可以随时附加和替换它。通过使用Microsoft.Extensions.Logging,您可以获得对结构化日志的支持。并且能够执行动态筛选,并用您最喜欢的选择替换日志接收器/目标。如果您只需要控制台日志记录,那么无需选择任何日志记录框架。这是适配器模式吗?看起来不像。我的意思是,如果你至少尝试过单身模式,那么也许我会投上一票。这只是一个静态的“全局”,违反了实体。当然可以。
static void Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
Startup startup = new Startup();
startup.ConfigureServices(services);
IServiceProvider serviceProvider = services.BuildServiceProvider();
// entry to run app
serviceProvider.GetService<ConsoleApp>().Run();
}
public class Startup
{
IConfigurationRoot Configuration { get; }
public Startup()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfigurationRoot>(Configuration);
services.AddSingleton<IMyConfiguration, MyConfiguration>();
services.AddLogging(loggingBuilder => {
loggingBuilder.AddNLog("nlog.config");
});
services.AddTransient<ConsoleApp>();
}
}
public class ConsoleApp
{
private readonly ILogger<ConsoleApp> _logger;
private readonly IMyConfiguration _config;
public ConsoleApp(IMyConfiguration configurationRoot, ILogger<ConsoleApp> logger)
{
_logger = logger;
_config = configurationRoot;
}
public void Run()
{
var test = _config.YourItem;
_logger.LogCritical(test);
System.Console.ReadKey();
}
}
public class MyConfiguration : IMyConfiguration
{
IConfigurationRoot _configurationRoot;
public MyConfiguration(IConfigurationRoot configurationRoot)
{
_configurationRoot = configurationRoot;
}
public string YourItem => _configurationRoot["YourItem"];
}
public interface IMyConfiguration
{
string YourItem { get; }
}