aop 0.9.1
aop: ^0.9.1 copied to clipboard
aop framework for dart - aka, the final transformer
TRIVIAL AOP framework for Dart #
A very simple AOP framework for Dart.
Premise #
Dart has transformers. They're used for several different purposes but one of the most common is to inject code. AOP should be a better framework for doing this kind of things.
Usage #
Declare your aspect anywhere in your code, for example:
import "package:aop/aop.dart";
@aspect
class MySampleAspect {
@Pointcut(const AnnotationMatches("pippo"))
executeAround(InvocationContext context, Function proceed) {
print("BEFORE (myAspect)");
var res = proceed();
print("AFTER (myAspect)");
return res;
}
}
This defines an aspect that will print a message before and after execution of any method in your code that is
annotated with @pippo.
An aspect is just a class annotated with @aspect.
Pointcut are defined using the annotation @Pointcut. The annotation constructor argument is a const expression
that defines the pointcut.
At the moment the expression is limited to:
NameMatchesto match the method name (using a regexp)AnnotationMatchesto match an annotation of the methodIsGetter/IsSetterto check if the method is a getter or setterAnd,Or,Nottry to guess ?
Also you can only write around pointcut for method.
Using IsGetter or IsSetter on a property will cause the pointcut to be called for both read and write operation on that property.
The InvocationContext will have a getter or setter property set to true to distinguish the one from the other.
For example aop can be used to automatically call set method on a polymer 1.0 component:
@aspect
class AutoSetter {
@Pointcut(const And(const [const AnnotationMatches("property"), const IsGetter()]))
callSetter(InvocationContext context, Function proceed) {
if(context.setter) {
(context.target as PolymerElement).set(
context.methodName, context.positionalParameters[0]);
//context.target.set()
}
}
}
the transformer #
To inject pointcut executions a trasformer need to be added to your pubspec configuration. The trasformer needs a list of entry_points to be configured.
It uses initialize so if used with polymer there's nothing else to do, otherwise you have to add initialize trasformer too.
For example:
transformers:
- aop:
entry_points: web/index.dart
- polymer:
entry_points: web/index.html
entry point #
The main entry point needs to call initialize run method to get the aop framework properly initialized, for example:
main() async {
await run();
await initPolymer();
}
next step #
More expressions (for example class selector, annotation on classes). Aspect lifecycle and scope. Support for property. Support for mixin injection.