Ich habe gerade diesen Vortrag von Greg Young gesehen, der die Leute zu KISS warnt: Keep It Simple Stupid.
Eines der Dinge , schlug er vor, dass die aspektorientierte Programmierung zu tun, man hat nicht einen Rahmen braucht .
Er beginnt mit einer starken Einschränkung: Alle Methoden verwenden nur einen einzigen Parameter ( dies wird jedoch etwas später durch teilweise Anwendung gelockert ).
Das Beispiel, das er gibt, besteht darin, eine Schnittstelle zu definieren:
public interface IConsumes<T>
{
void Consume(T message);
}
Wenn wir einen Befehl ausgeben wollen:
public class Command
{
public string SomeInformation;
public int ID;
public override string ToString()
{
return ID + " : " + SomeInformation + Environment.NewLine;
}
}
Der Befehl wird implementiert als:
public class CommandService : IConsumes<Command>
{
private IConsumes<Command> _next;
public CommandService(IConsumes<Command> cmd = null)
{
_next = cmd;
}
public void Consume(Command message)
{
Console.WriteLine("Command complete!");
if (_next != null)
_next.Consume(message);
}
}
Um sich an der Konsole anzumelden, muss man nur Folgendes implementieren:
public class Logger<T> : IConsumes<T>
{
private readonly IConsumes<T> _next;
public Logger(IConsumes<T> next)
{
_next = next;
}
public void Consume(T message)
{
Log(message);
if (_next != null)
_next.Consume(message);
}
private void Log(T message)
{
Console.WriteLine(message);
}
}
Dann sind die Protokollierung vor dem Befehl, der Befehlsservice und die Protokollierung nach dem Befehl einfach:
var log1 = new Logger<Command>(null);
var svr = new CommandService(log);
var startOfChain = new Logger<Command>(svr);
und der Befehl wird ausgeführt von:
var cmd = new Command();
startOfChain.Consume(cmd);
Um dies zum Beispiel in PostSharp zu tun , würde man dies folgendermaßen kommentieren CommandService
:
public class CommandService : IConsumes<Command>
{
[Trace]
public void Consume(Command message)
{
Console.WriteLine("Command complete!");
}
}
Und dann müssen Sie die Protokollierung in einer Attributklasse implementieren, wie etwa:
[Serializable]
public class TraceAttribute : OnMethodBoundaryAspect
{
public override void OnEntry( MethodExecutionArgs args )
{
Console.WriteLine(args.Method.Name + " : Entered!" );
}
public override void OnSuccess( MethodExecutionArgs args )
{
Console.WriteLine(args.Method.Name + " : Exited!" );
}
public override void OnException( MethodExecutionArgs args )
{
Console.WriteLine(args.Method.Name + " : EX : " + args.Exception.Message );
}
}
Das Argument, das Greg verwendet, ist, dass die Verbindung vom Attribut zur Implementierung des Attributs "zu magisch" ist, um erklären zu können, was mit einem Junior-Entwickler geschieht. Das erste Beispiel ist alles "nur Code" und leicht zu erklären.
Nach diesem langwierigen Aufbau lautet die Frage also: Wann stellen Sie den Wechsel von Gregs Nicht-Framework-Ansatz auf die Verwendung von PostSharp für AOP um?
IConsumes
Teile miteinander verbindet. Anstatt externes XML oder eine Fluent-Schnittstelle verwenden zu müssen - noch eine andere Sache zum Lernen. Man könnte argumentieren, dass diese Methodik auch "eine andere Sache zu lernen" ist.