Ответ 1
Вам нужно определить прокси-регистратор, который направляет сообщение правильному Nlog Logger. Этот прокси-сервер довольно прост:
public class NLogProxy<T> : ILogger
{
private static readonly NLog.ILogger logger =
LogManager.GetLogger(typeof (T).FullName);
void ILogger.Log(string message)
{
logger.Log(LogLevel.Info, message);
}
}
Вы можете зарегистрировать это как
container.RegisterConditional(typeof(ILogger),
context => typeof(NLogProxy<>).MakeGenericType(context.Consumer.ImplementationType),
Lifestyle.Singleton, context => true);
Всюду, где вам нужно вести журнал, вам нужно будет вводить ILogger
.
Что касается АОП. Я не уверен, что вы подразумеваете под этим комментарием.
Обертка, которая должна поддерживаться (контракт NLog.ILogger огромен).
Ведение журнала - это проблема перекрестных связей и использование decorator - отличный способ применить проблемы перекрестной резки. С помощью декоратора невозможно будет зарегистрировать каждый (закрытый) вход и выход вызова функции, но зачем вам это нужно? Как вы можете прочитать здесь, вам, вероятно, это не нужно. Простой факт, что услуга вызывается (с данными, переданными этой службе) и возможными исключениями, регистрируется с полным стеком, будет в большинстве случаев более чем достаточным.
Поэтому рассмотрим следующее:
public interface ISomeService
{
void DoSomething(string someParameter);
}
public class SomeServiceDecorator : ISomeService
{
private readonly ISomeService decoratee;
private readonly ILogger logger;
public SomeServiceDecorator(ISomeService decoratee, ILogger logger)
{
this.decoratee = decoratee;
this.logger = logger;
}
public void DoSomething(string someParameter)
{
try
{
this.logger.Log(string.Format("Do something called with {0}", someParameter));
this.decoratee.DoSomething(someParameter);
}
catch (Exception e)
{
this.logger.Log(e.ToString());
throw;
}
}
}
Этот декоратор будет записывать все вызовы функций с информацией, переданной службе, а также регистрирует любое исключение.
Но этот подход увеличил бы количество классов на 2, поэтому не очень DRY. Эта проблема вызвана тем, что этот проект по крайней мере субоптимален. Использование дизайна вокруг одной открытой общей абстракции полностью решит эту проблему. Вы можете прочитать об этом проекте здесь и здесь.
В этом случае у вас будет один "LoggingDecorator" как
public class LoggingCommandHandlerDecorator<T> : ICommandHandler<T>
{
private readonly ICommandHandler<T> decoratee;
private readonly ILogger logger;
public LoggingCommandHandlerDecorator(ICommandHandler<T> decoratee, ILogger logger)
{
this.decoratee = decoratee;
this.logger = logger;
}
public void Handle(T command)
{
// serialize command to json and log
this.logger.Log(serializedcommandData);
this.decoratee.Handle(command);
}
}
И этот единственный декоратор будет записывать все ваши команды.
Это мое видение АОП....