1 <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN">
4 <meta content=
"text/html;charset=ISO-8859-1" http-equiv=
"content-type">
5 <meta content=
"en" http-equiv=
"content-language">
6 <meta name=
"robots" content=
"index, follow/">
7 <meta name=
"keywords" content=
"AOP, Aspect, Aspect Oriented Programming, .NET, DotNet, C#, Aspect .Net, Aspect Sharp, AspectSharp, Aspect #, Aspect#, AOP .Net, Aspect Oriented Programming .NET " />
8 <meta name=
"description" content=
"A .NET AOP Framework, it uses Dynamic Proxies and XML configuration files as basis." />
9 <title>Aspect# Language Documentation
</title>
10 <style type=
"text/css">
35 font-family:"Lucida Console", "Courier New", Courier
;
37 background-color: #DDDDDD;
39 border: 2px dashed
#000000;
49 <table border=
"1" cellspacing=
"0" bordercolor=
"black" width=
"100%">
51 <td>Aspect# - An AOP framework for the .NET
</td>
55 <h1><img src=
"http://aspectsharp.sourceforge.net/logo.gif" alt=
"Aspect# Logo. By Ricardo Aloise." /></h1>
60 <h3>Aspect# Language Documentation
</h3>
62 <p> The purpose of Aspect# language is to offer you a cleaner way to configure,
63 describe and document your aspects configuration without have to rely on creepy
64 xml syntax to do so.
</p>
66 <h4>Basic definitions
</h4>
67 <p>You must obey to a few rules to use the Aspect# language, and the first rule
68 is that order matters. So you declarations must obey this sequence:
</p>
72 [Global Interceptor map]
80 <p>The imports section helps you to keep a clean code and helps the language to
81 resolve the types.
</p>
82 <pre class=
"code">Import Namespace.Name [in AssemblyName]
</pre>
84 <pre class=
"code">Import System.Collections in System
</pre><br/>
85 <pre class=
"code">Import AspectSharp.Core
</pre>
88 <h4>Global Interceptors
</h4>
89 <p>In the case that you have an interceptor that is going to be used in more than
90 one aspect - or even more than one pointcut, you can define it in an global
91 interceptor section:
</p>
94 "key
" : InterceptorType ;
95 "key2
" : InterceptorType2
100 "logger" : DigitalGravity.Interceptors.Logger in DigitalGravity.XProject
104 Import DigitalGravity.Interceptors in DigitalGravity.XProject
110 <p>Once you've done it, you can refer to them in an aspect declaration by their
113 aspect Test for MyClass
127 <h4>Global Mixins
</h4>
128 <p>For the same reason there is also a mixin global section:
</p>
131 "key
" : MixinType ;
132 "key2
" : MixinType2
137 "security" : DigitalGravity.Mixins.SecurityMixin in DigitalGravity.XProject
141 Import DigitalGravity.Mixins in DigitalGravity.XProject
144 "security" : SecurityMixin
147 <p>Once you've done it, you can refer to them in an aspect declaration by their
150 aspect Test for MyClass
159 <p>An aspect section defines which mixins and which pointcuts will be applied to a type or a set of types:
</p>
168 aspect MyAspect for Customer
173 aspect MyAspect for [ My.Namespace.Classes excludes(Customer,Author) ]
178 aspect MyAspect for [ assignableFrom(Customer) ]
183 aspect MyAspect for [ customMatcher(MyAspectMatcher) ]
187 When you invoke the AspectEngine.Wrap method on an instance, basically Aspect# will try to match
188 the aspects for that particular instance. If more than one are matched, a new aspect is created from
189 the union and will be used as the aspect definition.
192 If you need a more specific semantic to match aspects, you can provide your own using the
193 customMatcher keyword (as the example above). Your class must implement the IClassMatcher interface
194 and perform its logic returning true if the instance is eligible for that aspect.
198 <p>You use one or more include to add mixins to the resulting type in an aspect definition.
</p>
201 aspect MyAspect for Customer
202 include DigitalGravity.Mixins.Security in DigitalGravity.XProject
203 include System.Collections.ArrayList in System
207 <p><h4>Pointcuts
</h4></p>
208 <p>The purpose of pointcuts is to define an expression that must be true (matched) in order
209 to introduce advices.
</p>
211 pointcut [target][method signature]
216 <p>The possible targets are:
</p>
220 <li>propertyread
</li>
221 <li>propertywrite
</li>
223 <p>You can also combine them if you want, provided that they make sense
</p>
225 pointcut method|property(*)
228 pointcut method|propertyread(*)
231 pointcut propertywrite(*)
234 <p>Using property|propertywrite for instance is meaningless, and you'll get an error.
</p>
235 <p>The method signature can be simple as a (*) meaning everything, or (System.IList Create(int, *)) meaning
236 methods named Create that returns System.IList and have at least the first argument of the type int.
237 <b>Please note that return types and argument types here are not resolved, so you have to use
238 the full type name.
</b>
240 <p>Regular expressions are not fully supported. In fact, you can use only .* to match something
241 in the rest of an name like (Str.* Create(int, string)) that will match Create methods with two
242 arguments (the first an int and the second a String) and returning a type which the name starts with
243 Str, like String, Strange, Stripissimo and so on.
</p>
246 // All read and write property named Name
247 pointcut property(* Name)
250 // All read and write property named
251 // C****Name like CustomerName
252 pointcut property(string C.*Name)
255 // The method Perform returning void with no arguments
256 pointcut method(void Perform)
259 // The method Perform with the first argument as String
260 // and we don't care about the other arguments
261 pointcut method(void Perform(string, *))
265 <p><h4>Advices
</h4></p>
266 <p>Advices are the pieces of code that will be associated with a given joinpoint.
267 Aspect# only supports MethodInterceptors advices.
269 <p><b>Please note that we use lazy instantiation of interceptors and
270 only one instance of an interceptor will exist per Wrap(). In other words, proxies
271 will not share interceptors.
</b>
275 aspect MyAspect for Customer
277 advice(DigitalGravity.Interceptors.LogInvocationInterceptor in DigitalGravity.XProject)
283 <p>20-
09-
04 - The Aspect# Team