Я просто смотрел этот разговор по Greg Молодых предупреждений людей к ПОЦЕЛУЮ: Keep It Simple Stupid.
Одна из вещей , которые он предложил, что делать аспектно-ориентированное программирование, один вовсе не нужны рамки .
Он начинает с строгого ограничения: все методы принимают один и только один параметр (хотя он ослабляет это чуть позже, используя частичное применение ).
Пример, который он приводит, - определить интерфейс:
public interface IConsumes<T>
{
void Consume(T message);
}
Если мы хотим выполнить команду:
public class Command
{
public string SomeInformation;
public int ID;
public override string ToString()
{
return ID + " : " + SomeInformation + Environment.NewLine;
}
}
Команда реализована так:
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);
}
}
Чтобы войти в консоль, нужно просто выполнить:
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);
}
}
Затем ведение журнала перед командой, служба команд и запись после команды просто:
var log1 = new Logger<Command>(null);
var svr = new CommandService(log);
var startOfChain = new Logger<Command>(svr);
и команда выполняется:
var cmd = new Command();
startOfChain.Consume(cmd);
Чтобы сделать это, например, в PostSharp , можно аннотировать CommandService
так:
public class CommandService : IConsumes<Command>
{
[Trace]
public void Consume(Command message)
{
Console.WriteLine("Command complete!");
}
}
И тогда придется реализовать запись в класс атрибута что-то вроде:
[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 );
}
}
Аргумент, который использует Грег, заключается в том, что связь между атрибутом и реализацией атрибута «слишком большая магия», чтобы можно было объяснить, что происходит с младшим разработчиком. Начальный пример - это просто код и его легко объяснить.
Итак, после этого довольно затянувшегося процесса создания возникает вопрос: когда вы переключаетесь с неструктурного подхода Грега на использование чего-то вроде PostSharp для AOP?
IConsumes
части. Вместо того, чтобы использовать внешний XML или некоторый интерфейс Fluent - еще одна вещь для изучения. Можно утверждать, что эта методология также «еще одна вещь для изучения».