Я просто дивився цю розмову по 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 --- ще одна річ, яку слід вивчити. Можна стверджувати, що ця методологія також "інша річ, яку потрібно вивчити".