|Developing Simple Aspects|
In PostSharp, developing an aspect is as simple as deriving a primitive aspect class and overriding some special methods named advice. Aspects encapsulate a transformation of an element of code (such as a method or a property), and advices are the methods that are executed at runtime.
For instance, the effect of the aspect OnMethodBoundaryAspect is to wrap the target method into a try/catch/finally construct, and the advices of this aspect are OnEntry(MethodExecutionArgs), OnSuccess(MethodExecutionArgs), OnException(MethodExecutionArgs) and OnExit(MethodExecutionArgs)
By default, advices of primitive aspect types have an empty implementation, so the aspect has no effect until you override at least one advice.
To develop a simple aspect:
Add PostSharp to your project. See Installing PostSharp Tools for Visual Studio for details.
Create a new class and make it derive from one of the primitive aspect classes (see below).
Override one of the aspect advice methods.
The following table gives a list of available primitive aspect classes. Every aspect class is described in greater detailed in the class reference documentation.
Methods enhanced with an OnMethodBoundaryAspect are wrapped by a try/catch/finally construct. This aspect provides the advices OnEntry(MethodExecutionArgs), OnSuccess(MethodExecutionArgs), OnException(MethodExecutionArgs) and OnExit(MethodExecutionArgs); these advices are invoked directly from the transformed method, the return value, and the exception (if applicable). This aspect is useful to implement tracing or transaction handling, for instance.
For details, see Injecting Behaviors Before and After Method Execution.
Methods enhanced with an OnExceptionAspect are wrapped by a try/catch construct. This aspect provides the advice OnException(MethodExecutionArgs); this advice is invoked from the catch block. This aspect is useful to implement exception handling policies. Contrarily to OnMethodBoundaryAspect, this aspect lets you define the type of caught exceptions by overriding the method GetExceptionType(MethodBase)
For details, see Handling Exceptions.
When a method is enhanced by a MethodInterceptionAspect, all calls to this method are replaced by calls to OnInvoke(MethodInterceptionArgs), the only advice of this aspect type. This aspect is useful when the execution of target method can be deferred (asynchronous calls), must be dispatched on a different thread.
For details, see Intercepting Methods.
When a field or a property is enhanced by a LocationInterceptionAspect, all calls to its accessors are replaced by calls to advices OnGetValue(LocationInterceptionArgs) and OnSetValue(LocationInterceptionArgs). Fields are transparently replaced by properties. This aspect is useful to implement functionalities that need to get or set the location value, such as the observability design pattern (INotifyPropertyChanged).
For details, see Intercepting Properties and Fields.
When an event is enhanced by an EventInterceptionAspect, all calls to its add and remove semantics are replaced by calls to advices OnAddHandler(EventInterceptionArgs) and OnRemoveHandler(EventInterceptionArgs). Additionally, when the event is fired, even of invoking directly the handlers that were added to the event, the advice OnInvokeHandler(EventInterceptionArgs) is called instead. This aspect is useful to add functionalities to events, such as implementing asynchronous events or materialized list of subscribers.
For details, see Intercepting Events.
This aspect introduces an interface into a type by composition. The interface is introduced statically; the aspect method GetPublicInterfaces(Type) should return the type of introduced interfaces. However, the object implementing the interface is created dynamically at runtime by the implementation of the method CreateImplementationObject(AdviceArgs).
For details, see Introducing Interfaces.
For details, see Introducing Custom Attributes.
This aspect introduces a managed resource into the current assembly.
For details, see Introducing Managed Resources.
Fields, Properties, Parameters
This aspect causes any new value assigned to its target to be validated. If the aspect determines the value is invalid, an exception is thrown. The aspects of the PostSharp.Patterns.Contracts namespace are built on the top of this interface aspect.
For details, see Contracts.
The primitive aspect classes listed above only exist for convenience. In reality, PostSharp only understands interfaces. Every of these aspect classes implements a pair of interfaces. For instance, the class OnMethodBoundaryAspect implements the interfaces IOnMethodBoundaryAspect and IMethodLevelAspectBuildSemantics.
The aspect classes are more convenient because they derive from MulticastAttribute, which extends System.Attribute with multicasting capability. See Adding Aspects to Multiple Declarations for details.
If you do not need or want the capabilities of MulticastAttribute (for instance because the aspect is not used as a custom attribute, see IAspectProvider), you can implement the aspect interface manually. An aspect class must implement an interface derived from IAspect, and may implement an interface derived from IAspectBuildSemantics. Please refer to the documentation of the aspect class to get information about the corresponding aspect interface.
Additionally to the aspect interface corresponding to an aspect class, you can define the following interfaces on aspect classes:
By default, aspects have static scope: there is one instance of the aspect per target class. Implementing the IInstanceScopedAspect makes the aspect instance-scoped: there will be one instance of this aspect per instance of the target class.