Dashboard > Demonstration Space > ... > AspectSharp > AspectSharp Language Documentation
  Demonstration Space Log In | Sign Up   View a printable version of the current page.  
  AspectSharp Language Documentation
Added by James Curran, last edited by James Curran on Dec 25, 2007  (view change)
Labels: 
(None)

The purpose of Aspect# language is to offer you a cleaner way to configure, describe and document your aspects configuration without have to rely on creepy xml syntax to do so.

Table of contents

  1. Basic definitions
  2. Imports
  3. Global Interceptors
  4. Global Mixins
  5. Aspects
  6. Includes
  7. Pointcuts
  8. Advices

Basic definitions

You must obey to a few rules to use the Aspect# language, and the first rule is that order matters. So your declarations must obey this sequence:

[Imports]

[Global Interceptor map]

[Global Mixin map]

Aspects definitions

Imports

The imports section helps you to keep a clean code and helps the language to resolve the types.

Import Namespace.Name [in AssemblyName]

Examples:

Import System.Collections in System

Import AspectSharp.Core

Global Interceptors

In the case that you have an interceptor that is going to be used in more than one aspect - or even more than one pointcut, you can define it in an global interceptor section:

interceptors [
"key" :InterceptorType ;
"key2" : InterceptorType2
]

Examples

interceptors [
"logger" : DigitalGravity.Interceptors.Logger in DigitalGravity.XProject
]

Import DigitalGravity.Interceptors in DigitalGravity.XProject

interceptors [
"logger" : Logger
]

Once you've done it, you can refer to them in an aspect declaration by their keys:

aspect Test for MyClass
pointcut method(*y)
advice("key")
end

pointcut property(*y)
advice("key2")
end

end

Global Mixins

For the same reason there is also a mixin global section:

mixins [
"key" : MixinType ;
"key2" : MixinType2
]

Examples

mixins [
"security" : DigitalGravity.Mixins.SecurityMixin in DigitalGravity.XProject
]

Import DigitalGravity.Mixins in DigitalGravity.XProject

mixins [
"security" : SecurityMixin
]

Once you've done it, you can refer to them in an aspect declaration by their keys:

aspect Test for MyClass

include("security")

end

Aspects

An aspect section defines which mixins and which pointcuts will be applied to a type or a set of types:

aspect Name for Type
[include]
[pointcuts]
end

Examples

aspect MyAspect for Customer
end

aspect MyAspect for [ My.Namespace.Classes excludes(Customer,Author) ]
end

aspect MyAspect for [ assignableFrom(Customer) ]
end

aspect MyAspect for [ customMatcher(MyAspectMatcher) ]
end

When you invoke the AspectEngine.Wrap method on an instance, basically Aspect# will try to match the aspects for that particular instance. If more than one are matched, a new aspect is created from the union and will be used as the aspect definition.

If you need a more specific semantic to match aspects, you can provide your own using the customMatcher keyword (as the example above). Your class must implement the IClassMatcher interface and perform its logic returning true if the instance is eligible for that aspect.

Includes

You use one or more include to add mixins to the resulting type in an aspect definition.

Examples

aspect MyAspect for Customer
include DigitalGravity.Mixins.Security in DigitalGravity.XProject
include System.Collections.ArrayList in System
end

Pointcuts

The purpose of pointcuts is to define an expression that must be true (matched) in order to introduce advices.

pointcut [target][method signature]
advice(type)
advice("key")
end

The possible targets are:

  • method
  • property
  • propertyread
  • propertywrite

You can also combine them if you want, provided that they make sense

pointcut method|property(*)
end

pointcut method|propertyread(*)
end

pointcut propertywrite(*)
end

Using property|propertywrite for instance is meaningless, and you'll get an error.

The method signature can be simple as a meaning everything, or (System.IList Create(int, *)) meaning methods named Create that returns System.IList and have at least the first argument of the type int. Please note that return types and argument types here are not resolved, so you have to use the full type name.

Regular expressions are not fully supported. In fact, you can use only .* to match something in the rest of an name like (Str.* Create(int, string)) that will match Create methods with two arguments (the first an int and the second a String) and returning a type which the name starts with Str, like String, Strange, Stripissimo and so on.

Examples

// All read and write property named Name
pointcut property(* Name)
end

// All read and write property named
// C****Name like CustomerName
pointcut property(string C.*Name)
end

// The method Perform returning void with no arguments
pointcut method(void Perform)
end

// The method Perform with the first argument as String
// and we don't care about the other arguments
pointcut method(void Perform(string, *))
end

Advices

Advices are the pieces of code that will be associated with a given joinpoint. Aspect# only supports MethodInterceptors advices.

Please note that we use lazy instantiation of interceptors and only one instance of an interceptor will exist per Wrap(). In other words, proxies will not share interceptors.

Examples

aspect MyAspect for Customer
pointcut method(*)
advice(LogInvocationInterceptor)
end
end

aspect MyAspect for Customer
pointcut method(*)
advice(Namespace.MyLogger in MyAssembly)
end
end

(transfered from wiki.castleproject.org)

Site running on a free Atlassian Confluence Community License granted to Castle Project. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.4 Build:#809 Jun 12, 2007) - Bug/feature request - Contact Administrators