ts-advice
v0.9.7
Published
PlaceHolder
Downloads
2
Maintainers
Readme
Aspect Oriented Programming
Getting started
At first create a managed class using the @Managed()
decorator.
@Managed('Foo')
class ManagedExampleClass {
a: string = 'aaa'
b: string
constructor(b: string = 'b') {
this.b = b
}
getValue(additional: string = '') {
return this.a + this.b + additional
}
upperCased(str: string) {
return str.toUpperCase()
}
}
Then create an aspect.
@Aspect
class TestAspect {
protected prefix = 'from_cache'
protected cache = new Map<string, any>()
@Before(test, '->getValue()')
beforeGetValue(jointPoint: BeforeJointPoint) {
jointPoint.setArguments(['set from before'])
}
@After(ManagedExampleClass, '->getValue()')
afterGetValue(jointPoint: AfterJointPoint) {
return jointPoint.getLastReturn().toUpperCase()
}
@Around('Foo->upperCased()')
cache(jointPoint: AroundJointPoint) {
const id = jointPoint.getArguments().join('_')
if (this.cache.has(id)) {
return jointPoint.break(this.prefix + ':' + this.cache.get(id))
}
const ret = jointPoint.proceed()
this.cache.set(id, ret)
return ret
}
}
Using the ManagedClass
// @Managed('Foo')
// class ManagedExampleClass { ... }
const test = new ManagedExampleClass('ccc')
// class TestAspect { ... }
console.log(test.getValue('ddd')) // prints: AAACCCSET FROM BEFORE
console.log(test.upperCased('asdf')) // prints: ASDF
console.log(test.upperCased('asdfa')) // prints: ASDFA
console.log(test.upperCased('asdf')) // prints: from_cache:ASDF
Managed Classes
Aspects can only be applied to @Managed(entryIdentifier?: string)
classes. The optional entryIdentifier
is used to assign a unique name to a class. If no entryIdentifier
is provided the class name gets used.
Example
@Managed('Foo')
class ManagedClass {
a: string = 'aaa'
b: string
constructor(b: string = 'b') {
this.b = b
}
getValue(additional: string = '') {
return this.a + this.b + additional
}
upperCased(a: string) {
return a.toUpperCase()
}
}
Aspect
Expressions
It is possible to declare an Aspect in three different ways.
Using an instance of a managed class:
@Before(instanceOfManagedExampleClass, '->getValue()')
Using the managed class itself:
@Before(ManagedExampleClass, '->getValue()')
Using the identifier defined with the @Managed('Foo')
annotation or the Classname if no identifier is provided
// @Managed('Foo')
// class ManagedExampleClass { }
// ...
@Before('Foo->getValue()')
// @Managed()
// class ManagedExampleClass { }
// ...
@Before('ManagedExampleClass->getValue()')