DI с NLog в net-core2.0 - PullRequest
       47

DI с NLog в net-core2.0

1 голос
/ 04 апреля 2019

У меня немного не хватает понимания с NLog в сетевом ядре 2.0. Я хочу создать класс с конструктором в своем консольном приложении.

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);
        //...
    }
}

и 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, ???);

    //...
}

Что я должен сделать, чтобы получить Microsoft.Extensions.Logging.ILogger<Bot> в моем Bot классе?В классе Программы у меня только NLog.ILogger.Какая лучшая практика для «частичного» DI?Я хочу передать строку botToken, WebProxy httpProxy в конструктор класса Bot, но хочу, чтобы ILogger<Bot> logger разрешал автоматически.

Возможно ли это?

У меня есть идея передать IOptions<ApplicationMode> appSettings в класс Bot, но это будет грязный код, не так ли?

1 Ответ

1 голос
/ 04 апреля 2019

Это

NLog.ILogger Logger = LogManager.GetCurrentClassLogger();

возвращает объект типа NLog.Logger.

С другой стороны, ваш класс ожидает параметр конструктора типа Microsoft.Extensions.Logging.ILogger<Bot>. Так что, хотя оба названы ILogger, на самом деле они совершенно разных типов.

Одним из ответов будет изменение вашего класса на NLog.Logger вместо Microsoft.Extensions.Logging.ILogger<Bot>. Тогда вы могли бы сделать это:

NLog.ILogger logger = LogManager.GetCurrentClassLogger();
_botClient = new Bot(appModel.BotConfiguration.BotToken, httpProxy, logger);

Это, вероятно, сработает. Единственное, что меня беспокоит, это то, что ваш класс Bot зависит от NLog. Прямо сейчас это зависит от абстракции фреймворка, что лучше, потому что это означает, что вы можете использовать NLog или заменить какой-либо другой регистратор.

Таким образом, чтобы оставить все как есть, вам нужно создать класс, который адаптирует NLog.ILogger к Microsoft.Extensions.Logging.ILogger<Bot>.

(Когда я дошел до этого момента, я сам начал писать адаптер. Именно тогда мне пришло в голову, что он почти наверняка уже существует.)

К счастью, NLog уже сделал это в NLog.Extensions.Logging , который вы добавляете как пакет NuGet. Это вполне логично, потому что не все, кто хочет использовать NLog, хотят помещать специфичные для NLog типы в каждый класс, для которого нужен регистратор.

Они предоставляют документацию о том, как настроить это в консольном приложении.


Я начал с этого:

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

... и задавался вопросом, как будет выглядеть реализация. Оказывается, это выглядит так: https://github.com/NLog/NLog.Extensions.Logging/blob/master/src/NLog.Extensions.Logging/Logging/NLogLogger.cs.

Я ошибался, если думал, что собираюсь придумать это.

...