Accessing Members of the Target Class
PostSharp makes it possible to import a delegate of a target class method, property or event into the aspect class, so that the aspect can invoke this member.
These mechanisms allow developers to encapsulate more design patterns using aspects.
Importing Members of the Target Class
Importing a member into an aspect allows this aspect to invoke the member. An aspect can import methods, properties, or fields.
To import a member of the target type into the aspect class:
Define a field into the aspect class, of the following type:
Member Kind Field Type Method A typed Delegate, typically one of the variants of Action or Func<TResult>. The delegate signature should exactly match the signature of the imported method. Property Property<TValue>, where the generic argument is the type of the property. Collection Indexer Property<TValue, TIndex>, where the first generic argument is the type of the property value and the second is the type of the index parameter. Indexers with more than one parameter are not supported. Event Event<TDelegate>, where the generic argument is the type of the event delegate (for instance EventHandler).
Make this field public. The field cannot be static.
Add the custom attribute ImportMemberAttribute to the field. As the constructor argument, pass the name of the member to be imported.
At runtime, the field is set to a delegate of the imported member. Properties and events are imported as set of delegates (Get, Set; Add, Remove). These delegates can be invoked by the aspect as any delegate.
The property IsRequired determines what happens if the member could not be found in the target class or in its parent. By default, the field will simply have the
null value if it could not be bound to a member. If the property IsRequired is set to
true, a compile-time error will be emitted.
Interactions Between Several Member Introductions and Imports
Although member introduction and import may seem simple advices at first sight, things become more complex when several advices try to introduce or import the same member. PostSharp handles these situations in a robust and predictable way. For this purpose, it is important to process classes, aspects and advices in a consistent order.
PostSharp enforces the following order:
Base classes are processed first, derived classes after. Therefore, when a class is being processed, all parent classes have already been fully processed.
Aspects targeting the same class are sorted (see Coping with Several Aspects on the Same Target) and executed.
Advices of the same aspect are sorted and executed in the following order:
Member imports which have the property Order set to
Members imports which have the property Order set to
AfterIntroductions(this is the default value).
Based on this well-defined order, the advices behave as follow:
|ImportMemberAttribute||No member, or private member defined in a parent class.||Error if IsRequired is
|Non-virtual member defined.||Member imported.|
|Virtual member defined.||If Order is
|IntroduceMemberAttribute||No member, or private member defined in a parent class.||Member introduced.|
|Non-virtual member defined in a parent class||Ignored if the property OverrideAction is
|Virtual member defined in a parent class||Introduce a new
|Member defined in the target class (virtual or not)||Fail by default or if the property OverrideAction is
* Move the previous method body to a new method so that the previous implementation can be imported by advices ImportMemberAttribute with the property Order set to
Override the method with the imported method.