Ho appena visto questo discorso di Greg Young avvertire le persone di KISS: Keep It Simple Stupid.
Una delle cose che ha suggerito è che per fare una programmazione orientata all'aspetto, non è necessario un framework .
Comincia con un forte vincolo: che tutti i metodi assumano uno e un solo parametro (anche se lo rilassa un po 'più tardi usando un'applicazione parziale ).
L'esempio che fornisce è definire un'interfaccia:
public interface IConsumes<T>
{
void Consume(T message);
}
Se vogliamo emettere un comando:
public class Command
{
public string SomeInformation;
public int ID;
public override string ToString()
{
return ID + " : " + SomeInformation + Environment.NewLine;
}
}
Il comando è implementato come:
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);
}
}
Per eseguire la registrazione sulla console, uno quindi implementa:
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);
}
}
Quindi, la registrazione pre-comando, il servizio comandi e la registrazione post-comando sono solo:
var log1 = new Logger<Command>(null);
var svr = new CommandService(log);
var startOfChain = new Logger<Command>(svr);
e il comando viene eseguito da:
var cmd = new Command();
startOfChain.Consume(cmd);
Per fare questo in PostSharp , ad esempio , si dovrebbe annotare in CommandService
questo modo:
public class CommandService : IConsumes<Command>
{
[Trace]
public void Consume(Command message)
{
Console.WriteLine("Command complete!");
}
}
E quindi è necessario implementare la registrazione in una classe di attributi qualcosa del tipo:
[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 );
}
}
L'argomento usato da Greg è che la connessione dall'attributo all'implementazione dell'attributo è "troppo magica" per poter spiegare cosa sta succedendo a uno sviluppatore junior. L'esempio iniziale è tutto "solo codice" e facilmente spiegabile.
Quindi, dopo quell'accumulo piuttosto prolisso, la domanda è: quando passi dall'approccio non-framework di Greg all'utilizzo di qualcosa come PostSharp per AOP?
IConsumes
pezzi. Piuttosto che dover usare XML esterno o qualche interfaccia fluida --- ancora un'altra cosa da imparare. Si potrebbe sostenere che questa metodologia è anche "un'altra cosa da imparare".