2017-01-08 10 views
4

У меня есть сетевое приложение .Net, которое я пытаюсь добавить в журнал через NLog. В предыдущих проектах, я просто использовал что-то вроде следующего в верхней части каждого класса:Инъекция зависимостей с NLog

private static Logger logger = LogManager.GetCurrentClassLogger(); 

Я пытаюсь следовать более передовому опыту с этим проектом, где это возможно.

Вопрос в том, как я могу вставить регистратор, который имеет полное имя класса, в который он вводится?

В моем файле startup.cs, до сих пор я получил следующее:

services.AddScoped<BLL.Logging.NLogLogger>(); 

На данный момент NLogLogger класс создает экземпляр NLog Logger через GetCurrentClassLogger(), которая при использовании будет только когда-либо сообщите имя как «BLL.Logging.NLogLogger», а не фактический класс, в который вводится регистратор.

Чтобы упростить вопрос и сделать его более универсальным: Как вы можете передать имя класса, в котором .Net Core собирается ввести класс?

Я думал о чем-то вроде ниже, но не знает, как достичь этого:

services.AddScoped<BLL.Logging.NLogLogger>(serviceProvider => new BLL.Logging.NLogLogger("class name here")); 
+0

Вы не можете.Это невозможно сделать с помощью встроенного контейнера ASP.NET Core. Для этого вам понадобится «реальный» контейнер DI, например Autofac или Simple Injector. – Steven

ответ

6

Использование DI указывает тип ILogger<T> вместо Logger, где T - тип класса, который использует регистратор, поэтому NLog будет знать об этом классе. Например:

public class TodoController : Controller 
{ 
    private readonly ILogger _logger; 

    public TodoController(ILogger<TodoController> logger) 
    { 
     _logger = logger; 
    } 
} 
+0

Ах, отлично, это именно то, что мне нужно, это намного чище, чем решение, которое я придумал, прежде чем я увижу ваш ответ. Меня беспокоит то, что метод logger.LogError() заставляет вас указывать eventID как пареметр - обычно я бы этого не делал и вместо этого использовал рендеринг макета $ {activityid}, поэтому на данный момент я ' m просто собирается установить значение 0, например, любые мысли/предложения относительно eventID? – Steviebob

+1

@Steviebob u может использовать эту версию метода https://github.com/aspnet/Logging/blob/master/src/Microsoft.Extensions.Logging.Abstractions/LoggerExtensions.cs#L273. Кроме того, LogError является методом расширения, и вы можете определить свою версию, если хотите использовать другую подпись метода. – Set

+0

@ Установленная ссылка, которую вы показали, сейчас мертва. Я попытался реализовать ваше предложение, чтобы использовать 'ILogger ', но не удалось - в библиотеке NLog нет библиотеки 'ILogger ' 4.4.12. Пожалуйста, помогите мне понять, что такое общая идея? Чтобы реализовать собственный 'ILogger ' как оболочку над 'NLog.ILogger'? – oleksa

2

Я думаю, что я понял, приемлемое решение, хотя и не совсем так, как я задал вопрос.

Прежде всего, я создаю «LoggerFactory», который имеет один метод под названием «GetLogger» (который создает конкретный NLog Logger и принимает имя класса в качестве параметра), и я ввожу эту фабрику вместо регистратора непосредственно.

LoggerFactory:

public class LoggerFactory : ILoggerFactory 
{ 
    public ILogger GetLogger(string fullyQualifiedClassName) 
    { 
     return new NLogLogger(fullyQualifiedClassName); 
    } 
} 

NLogLogger:

public class NLogLogger : ILogger, INLogLogger 
{ 
    NLog.Logger mylogger; 
    public NLogLogger(string fullyQualifiedClassName) 
    { 
     mylogger = NLog.LogManager.GetLogger(fullyQualifiedClassName); 
    } 
} 

Startup.cs:

services.AddScoped<BLL.Logging.ILoggerFactory>(); 

В в моем Contr класс Oller, у меня есть:

private BLL.Logging.ILogger logger;//my NLogLogger inherits this interface 

    public HomeController(BLL.Logging.ILoggerFactory loggerFactory) 
    { 
     logger = loggerFactory.GetLogger(this.GetType().FullName); 
    } 

Так что я фактически делается сейчас, скорее, чем инъекционные сам фактический Logger (который @Steven указанный не было бы возможным, как я пытался это сделать) , Я вместо этого применил эту утилиту для создания экземпляра регистратора, который обертывает NLog.

Я по-прежнему несут ответственность за создание регистратора внутри класса, но по крайней мере я отделился от базовой структуры ведения журнала (NLog).