Sie müssen einen Proxy-Logger definieren, der die Nachricht an den richtigen Log Logger weiterleitet. Dieser Proxy ist ziemlich einfach:
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);
}
}
Sie dies als registrieren
container.RegisterConditional(typeof(ILogger),
context => typeof(NLogProxy<>).MakeGenericType(context.Consumer.ImplementationType),
Lifestyle.Singleton, context => true);
Überall, wo Sie brauchen Anmeldung erhalten Sie nur ILogger
injizieren.
Wie für AOP. Ich bin nicht sicher, was Sie mit diesem Kommentar meinen
Ein Wrapper, der gepflegt werden muss (NLog.ILogger Vertrag ist riesig).
Logging ist ein cross cutting concern und decorator ist eine großartige Art und Weise Querschnittsthemen anzuwenden. Mit einem Dekorator wird es nicht möglich sein, jeden (privaten) Funktionsaufruf zu protokollieren, Eingang und Ausgang, aber warum möchten Sie das? Wie Sie here lesen können, brauchen Sie das wahrscheinlich nicht. Die einfache Tatsache, dass ein Service aufgerufen wird (mit den an diesen Service übergebenen Daten) und mögliche Ausnahmen werden mit dem kompletten Stacktrace protokolliert, ist in den meisten Fällen mehr als ausreichend.
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;
}
}
}
Dieser Dekorateur loggt alle Funktion mit dem an den Dienst weitergegeben Informationen aufruft und protokolliert auch jede Ausnahme:
dies so betrachten.
Aber dieser Ansatz würde die Anzahl der Klassen um 2 erhöhen, also nicht sehr DRY. Dieses Problem wird verursacht, weil dieses Design mindestens suboptimal ist. Die Verwendung eines Entwurfs um eine einzelne offene generische Abstraktion wird dieses Problem vollständig lösen. Sie können über dieses Design here und here lesen.
In diesem Fall würden Sie einen einzigen `LoggingDecorator‘ haben als
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);
}
}
Und dieses einzelne Dekorateur werden alle Ihre Befehle protokolliert.
Das ist meine Vision von AOP ....
was möchten Sie den Wert von 'LoggerName' zu sein? – qujck
Related: https://Stackoverflow.com/q/32952701/264697 – Steven
Anwendung von AOP-Techniken ist sehr nützlich, aber bitte bleiben Sie weg von Code Web-Tools. Wenden Sie AOP an, indem Sie Dekoratoren verwenden. Related: https://Stackoverflow.com/a/9915056/264697 – Steven