I have a little lack of understanding with NLog on net core 2.0 I want to create a class with constructor in my console app.
Bot.cs
public class Bot : IBot
{
static TelegramBotClient _botClient;
Microsoft.Extensions.Logging.ILogger<Bot> _logger;
public Bot(string botToken, WebProxy httpProxy, ILogger<Bot> logger)
{
_logger = logger;
_botClient = new TelegramBotClient(botToken, httpProxy);
//...
}
}
and Program.cs
public static async Task Main(string[] args)
{
//...
appModel = configuration.GetSection("ApplicationModel").Get<ApplicationModel>();
var userName = appModel.ProxyConfiguration.UserName;
var password = appModel.ProxyConfiguration.Password;
var httpProxy = new WebProxy(appModel.ProxyConfiguration.Url, appModel.ProxyConfiguration.Port)
{
Credentials = credentials
};
NLog.ILogger Logger = LogManager.GetCurrentClassLogger();
_botClient = new Bot(appModel.BotConfiguration.BotToken, httpProxy, ???);
//...
}
What should I do to get the Microsoft.Extensions.Logging.ILogger<Bot>
in my Bot
class? In Program class I have only NLog.ILogger
. What the best practice for "partial" DI? I want to pass string botToken, WebProxy httpProxy to constructor in Bot
class, but want ILogger<Bot>
logger resolve automatically.
Is it possible?
I have an idea to pass IOptions<ApplicationMode>
appSettings to Bot class, but it will be a dirty code, willn't it?
This
NLog.ILogger Logger = LogManager.GetCurrentClassLogger();
returns an object of type NLog.Logger
.
Your class, on the other hand, expects a constructor parameter of type Microsoft.Extensions.Logging.ILogger<Bot>
. So while both are named ILogger
they are actually entirely different types.
One answer would be to change your class to expect NLog.Logger
instead of Microsoft.Extensions.Logging.ILogger<Bot>
. Then you could do this:
NLog.ILogger logger = LogManager.GetCurrentClassLogger();
_botClient = new Bot(appModel.BotConfiguration.BotToken, httpProxy, logger);
That would probably work. The only minor concern I have there is that it makes your Bot
class depend on NLog. Right now it depends on a framework abstraction, which is better because it means you can use NLog or substitute some other logger.
So to keep it as-is, you would need to create a class that adapts NLog.ILogger
to Microsoft.Extensions.Logging.ILogger<Bot>
.
(When I got to this point I started writing the adapter myself. That's when it occurred to me that it almost certainly already existed.)
Fortunately, NLog has already done this in NLog.Extensions.Logging which you an add as a NuGet package. It makes perfect sense that they would provide this, as not everyone who wants to use NLog wants to put NLog-specific types in every class that needs a logger.
They provide documentation on how to configure this in a console app.
I started with this:
public class NLogger : ILogger
{
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
throw new NotImplementedException();
}
public bool IsEnabled(LogLevel logLevel)
{
throw new NotImplementedException();
}
public IDisposable BeginScope<TState>(TState state)
{
throw new NotImplementedException();
}
}
...and wondered what the implementation would look like. As it turns out, it looks like this: https://github.com/NLog/NLog.Extensions.Logging/blob/master/src/NLog.Extensions.Logging/Logging/NLogLogger.cs .
I was mistaken if I thought I was going to come up with that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.