Download demo project source code
Yesterday we went over creating an aspect and applying it to a method. PostSharp is flexible in how aspects can be applied which results in outstanding benefits for us as developers. Imagine our exception wrapper aspect automatically being applied to any new method that is added to any class in the project. What about logging exceptions? No longer do we have to remember to add exception logging code to new methods. Of course, the practical applications are far beyond these simple scenarios but it gives you an idea of the power of PostSharp.
OnExceptionAspect is intended to work with methods. Yesterday we applied our aspect to the target method directly, which did the job but
- What happens when we need to profile multiple methods?
- What happens when we want to profile every method in every class?
That's a lot of work if we were to manually apply the aspect to each method.
PostSharp comes with another aspect that we can use called OnMethodBoundaryAspect. This class allows us to intercept certain points in a method’s execution by providing 4 virtual methods we can override
- OnEntry - Before the execution of the method body
- OnExit - Always called when a method is done executing even if there was an error
- OnSuccess - Called only when a method is done executing and there were no exceptions
- OnException - Called only when a method has stopped executing due to an unhandled exception
To give a clear understanding of multicasting, we’ll build a simple tracing aspect that will log the entry and exit of a method as it’s executed. Add a new file called MethodTraceAspect.cs and add the following code
public class MethodTraceAspect : OnMethodBoundaryAspect
public override void OnEntry(MethodExecutionArgs args)
Debug.WriteLine(args.Method.Name + " started");
public override void OnExit(MethodExecutionArgs args)
Debug.WriteLine(args.Method.Name + " finished");
This aspect is the, “Hello World” of Aspect Oriented Programming, but it serves our purpose for today. When applied to a method this aspect will write ‘Started’ and ‘Finished’ to the output window. Go ahead and apply it to the GetByName method in InMemoryDataStore.cs file
public IQueryable GetByName(string value)
var res = _contactStore.Where(c => c.FirstName.Contains(value)
if (res.Count() < 1)
Run the application and do a search. As expected you see
In the output window.
Class Level Declaration
Instead of applying the aspect manually to every method, we can apply the aspect only once, on the class. PostSharp will automatically apply the aspect to all methods in the class. Let's try it. Remove the [MethodTraceAspect] from GetByName method and apply to the InMemoryDataStore class
internal class InMemoryDataStore : PostSharpDemo1.IContactRepository
When we run the application there is a lot more being displayed in the output window, just by starting the application.
Notice that there are calls to methods not in the class. Remember that property getters and setters are turned into methods when your code is compiled which makes them eligible for receiving the aspect. The .cctor entry is the static constructor and .ctor is the instance constructor.
As interesting as this is, you won’t always want to have the aspect applied to absolutely everything. There are a few ways to avoid aspect application on a specific target. We'll cover those tomorrow.
Today we saw another aspect we can take advantage of and we also saw how we can use multicasting to apply an aspect to multiple targets with one line of code. Tomorrow we’ll look at even more multicasting.