Ho appena guardato questo talk di Greg Young avvisa la gente di KISS: Keep It Simple Stupid.
Una delle cose che ha suggerito è che per fare programmazione orientata all'aspetto, uno non non ha bisogno di un framework .
Inizia facendo un strong vincolo: che tutti i metodi prendano uno, e solo uno, parametro (anche se lo rilassa un po 'più tardi utilizzando un'applicazione parziale ).
L'esempio che dà è 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 il logging su console, basta implementare:
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 ciò, ad esempio, PostSharp , si annoterebbe il CommandService
in questo modo:
public class CommandService : IConsumes<Command>
{
[Trace]
public void Consume(Command message)
{
Console.WriteLine("Command complete!");
}
}
E poi devi implementare la registrazione in una classe di attributi come:
[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 che Greg usa è che la connessione dall'attributo all'attuazione dell'attributo è "troppa magia" per essere in grado di spiegare cosa sta succedendo a uno sviluppatore junior. L'esempio iniziale è tutto "solo codice" e facilmente spiegabile.
Quindi, dopo quella build piuttosto lunga, la domanda è: quando si passa dall'approccio non-framework di Greg all'utilizzo di qualcosa come PostSharp per AOP?