Właśnie oglądałem tę rozmowę przez Grega Younga ostrzegania ludzi całować: Keep It Simple głupie.
Jedną z rzeczy, zasugerował, że aby zrobić programowanie aspektowe, jeden ma nie potrzebują ramy .
Zaczyna od silnego ograniczenia: wszystkie metody przyjmują jeden i tylko jeden parametr (choć nieco później rozluźnia to, stosując częściową aplikację ).
Podaje przykład, aby zdefiniować interfejs:
public interface IConsumes<T>
{
void Consume(T message);
}
Jeśli chcemy wydać polecenie:
public class Command
{
public string SomeInformation;
public int ID;
public override string ToString()
{
return ID + " : " + SomeInformation + Environment.NewLine;
}
}
Polecenie jest realizowane jako:
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);
}
}
Aby zalogować się do konsoli, wystarczy zaimplementować:
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);
}
}
Następnie rejestrowanie przed komendą, obsługa komend i rejestrowanie po komendach są następujące:
var log1 = new Logger<Command>(null);
var svr = new CommandService(log);
var startOfChain = new Logger<Command>(svr);
a polecenie jest wykonywane przez:
var cmd = new Command();
startOfChain.Consume(cmd);
Aby to zrobić na przykład w PostSharp , należy opisać w CommandService
następujący sposób:
public class CommandService : IConsumes<Command>
{
[Trace]
public void Consume(Command message)
{
Console.WriteLine("Command complete!");
}
}
A potem trzeba zaimplementować rejestrowanie w klasie atrybutów, takiej jak:
[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 );
}
}
Argument, który wykorzystuje Greg, jest taki, że połączenie atrybutu z implementacją atrybutu to „zbyt dużo magii”, aby móc wyjaśnić, co dzieje się z młodszym programistą. Początkowy przykład to „tylko kod” i można go łatwo wyjaśnić.
Tak więc po tym dość długotrwałym narastaniu pojawia się pytanie: kiedy przejdziesz z nieszkieletowego podejścia Grega do używania czegoś takiego jak PostSharp dla AOP?
IConsumes
elementy. Zamiast korzystać z zewnętrznego XML lub jakiegoś płynnego interfejsu --- jeszcze jedna rzecz do nauczenia się. Można argumentować, że ta metodologia to także „kolejna rzecz do nauczenia się”.