Archive

Source code used in these blog posts is available on GitHub

One of the best uses of AOP is to take cross-cutting concerns that repeat themselves over and over in your system, and move them into their own class. This is a version of the Single Responsibility Principle (SRP). Authentication and authorization are important parts of many applications, but too often the code to check if a user is authorized is spread all over the app, making logic changes difficult and regression common. A class should have one and only one reason to change, so let's get the "auth" stuff into its own class.

The main functionality of authentication isn't something that's normally spread out through an entire application. In a web app, for instance, login and authentication is typically done on one login page (if it's done at the web application level at all--it could be done at the server level), and login information is stored in some sort of token with an expiration on it so that the user is automatically logged out after a certain period of time. The only cross-cutting concern then, is that each web page that requires authentication needs to verify that the user is still logged in. You could certainly use PostSharp to do this, but it really isn't (in my opinion) a particularly strong use-case for PostSharp.

Authorization, on the other hand, is a great place to use PostSharp. Too often the logic about which user role is allowed to perform which activity is messily scattered all over the application, and PostSharp can be used to organize it, as well as provide reusable object-oriented components. Additionally, sometimes role-based security is too broad. A more finegrained control is sometimes needed, for instance to restrict editing data unless you are the user who first created it. Let's look at a sample application that's very similar to one I worked on as a consultant, and see how PostSharp can help.

An application is needed for users to fill out government forms. This would probably be a website, but I'll be using a WinForms app just to keep things simple for now. Each user can submit government forms (just a single textbox in my example). Administrators can delete the forms, but normal users can only submit (add) new forms and look at their existing forms.

I won't list all the code here, but here's a service class that provides basic functionality for the above requirements. This class is using a static collection as persistence, but of course a database, webservice, etc, would be used in a real app:

public class GovtFormService : IGovtFormService
{
	private static readonly IList _govtFormsDatabase = new List();

	public GovtFormService()
	{
		// build up some initial entries of the static list
	}

	public void SubmitForm(GovtForm form)
	{
		_govtFormsDatabase.Add(form);
	}

	public IEnumerable GetAllForms()
	{
		return _govtFormsDatabase;
	}

	public GovtForm GetFormById(Guid guid)
	{
		return _govtFormsDatabase.FirstOrDefault(form => form.FormId == guid);
	}
}

Just wire up that service to the Windows form, and wire up the buttons on the form to each of those methods, and you have a basic application. However, the requirement was that users should only be able to view the details of their own forms. GetFormById currently doesn't do any checking at all. We could put some if-statements in there, but let's instead create an aspect that we can use anywhere:

[Serializable]
public class AuthorizeReturnValueAttribute : OnMethodBoundaryAspect
{
	[NonSerialized] private IAuth Auth;

	public override void RuntimeInitialize(System.Reflection.MethodBase method)
	{
		Auth = new AuthService();
	}

	public override void OnSuccess(MethodExecutionArgs args)
	{
		var singleForm = args.ReturnValue as GovtForm;
		if (singleForm != null)
		{
			if(Auth.CurrentUserHasPermission(singleForm, Permission.Read))
			{
				MessageBox.Show(
				 "You are not authorized to view the details of that form",
				 "Authorization Denied!");
				args.ReturnValue = null;
			}
			return;
		}
	}
}

This is one way to approach it. Check to see if the method that is being intercepted is returning a GovtForm. If it is, make sure it's a form that belongs to the current user. Note that the IAuth field is marked as NonSerialized, and that it's initialized in the RuntimeInitialize override. Instead of hardcoding the dependency, you could use a IoC container as a service locator instead (see previous post about dependency inversion).

Add a bit more code to the aspect, and we can handle methods that return a whole collection of GovtForms by "filtering" out the ones that the current user doesn't have access to.

var formCollection = args.ReturnValue as IEnumerable;
if (formCollection != null)
{
	args.ReturnValue = formCollection
			.Where(f => Auth.CurrentUserHasPermission(f, Permission.Read));
	return;
}

Of course, there's nothing special about GovtForm, other than the fact that it has a UserName property. You could add an "ISecurable" interface to each business object class that you'd want to secure in this way, and then CurrentUserHasPermission would take an "ISecurable" argument rather than a GovtForm argument specifically. Finally, put the "AuthorizedRecordsOnly" attribute on any service/repository method that returns a single business object or collection of business objects, and away you go: only the records the user is allowed to see will be returned, and you didn't need to make any major coding changes to the UI or to the services.

Now that you have a couple of handy aspects under your belt, it's time to look at something a little more complex in the overall scheme of things. Suppose you have a Caching aspect AND an Authorization aspect on a method. Caching should probably come after authorization, otherwise unauthorized cached data might be returned. So how do you enforce that Authorization is applied first, followed by the Caching aspect? Here's how you do it:

1. Apply a ProvideAspectRoleAttribute to one or more of your aspects. This can be a custom string, or you can use the StandardRoles enumeration that comes with PostSharp

2. Apply an AspectRoleDependencyAttribute to one or more of your aspects to specify the type of dependency, and the role that it is dependent upon.

To fulfill the requirement that Authorization is applied first, then Caching, apply attributes to your aspects like so:

[Serializable]
[AspectRoleDependency(AspectDependencyAction.Order,
	AspectDependencyPosition.Before, StandardRoles.Caching)]
public class AuthorizeReturnValueAttribute : OnMethodBoundaryAspect
{
}

[Serializable]
[ProvideAspectRole(StandardRoles.Caching)]
public class CachingAttribute : OnMethodBoundaryAspect
{
	public override void OnEntry(MethodExecutionArgs args)
	{
		// do caching stuff
	}

	public override void OnSuccess(MethodExecutionArgs args)
	{
		// do caching stuff
	}
}

We're telling PostSharp that the Caching aspect belongs to the "Caching" role, and we're also telling PostSharp that the Authorization aspect should be applied "before" the Caching role. Here's what the result looks like in Reflector when I apply both aspects to the "GetAllForms" method:

public IEnumerable GetAllForms()
{
	MethodExecutionArgs CS$0$2__aspectArgs = new MethodExecutionArgs(null, null);
	<>z__Aspects.a1.OnEntry(CS$0$2__aspectArgs);
	IEnumerable CS$1$1__returnValue = _govtFormsDatabase;
	<>z__Aspects.a1.OnSuccess(CS$0$2__aspectArgs);
	CS$0$2__aspectArgs.ReturnValue = CS$1$1__returnValue;
	<>z__Aspects.a0.OnSuccess(CS$0$2__aspectArgs);
	return (IEnumerable) CS$0$2__aspectArgs.ReturnValue;
}

Just for demonstration, if I change Caching's AspectDependencyPosition to "Before" instead, here's what it looks like Reflector:

public IEnumerable GetAllForms()
{
	<>z__Aspects.a1.OnEntry(null);
	MethodExecutionArgs CS$0$2__aspectArgs = new MethodExecutionArgs(null, null);
	IEnumerable CS$1$1__returnValue = _govtFormsDatabase;
	CS$0$2__aspectArgs.ReturnValue = CS$1$1__returnValue;
	<>z__Aspects.a0.OnSuccess(CS$0$2__aspectArgs);
	CS$1$1__returnValue = (IEnumerable) CS$0$2__aspectArgs.ReturnValue;
	<>z__Aspects.a1.OnSuccess(null);
	return CS$1$1__returnValue;
}

Notice that a1 (caching) and a0 (authorization) usages are changed around.

You have a lot of flexibility here to define dependencies if you need to: there are five dependency actions you can use (Commute, Conflict, Order, Require, and None), and besides StandardRoles, you can create an unlimited number of roles named by strings. Hopefully, you won't need to use this feature too much, but it's good to know that it's there if you do. The great thing is that this type of aspect composition allows you to relax knowing that even the newest member of team won't accidentally expose unauthorized data, no matter what order he lists the aspect attributes in the code.

Matthew D. Groves is a software development engineer at Telligent, and blogs at mgroves.com.

Source code used in these blog posts is available on GitHub

Logging and auditing is one of the things that PostSharp is best at. It's the quintessential example of a cross-cutting concern. Instead of sprinkling logging code all throughout the app, you simply write a logging aspect in one place. You can apply it selectively or on the whole app.

You can get a lot of useful information with an aspect, but there are three popular categories:

  • Code information: function name, class name, parameter values, etc. This can help you to reduce guessing in pinning down logic flaws or edge-case scenarios
  • Performance information: keep track of how much time a method is taking
  • Exceptions: catch select/all exceptions and log information about them

In contrast to logging/tracing, which is a technical issue, you can also use PostSharp for auditing, which is very similar to logging/tracing, except that auditing keeps track of information of a more business-nature. For instance, you may want to log parameter values to help fix bugs, and you may want to audit how many times a user performs a certain business activity (like a ‘deposit' for instance) in a given time frame. Typically a log may only need to write to a text file or very simple database table, while auditing may end up in a database table that's accessible in the application itself. Auditing may be closely tied to the authentication/authorization as well.

Let's use a simplified bank teller application. Let's say that this app can be used by live tellers or ATMs, and we'll simulate both with one simple WinForms UI. Also, the bank only has one customer for our purposes, and uses the following static class as the entire (very naive) business logic.

public class BankAccount
{
	static BankAccount()
	{
		Balance = 0;
	}
	public static decimal Balance { get; private set; }

	public static void Deposit(decimal amount)
	{
		Balance += amount;
	}

	public static void Withdrawl(decimal amount)
	{
		Balance -= amount;
	}

	public static void Credit(decimal amount)
	{
		Balance += amount;
	}

	public static void Fee(decimal amount)
	{
		Balance -= amount;
	}
}

Of course, in a real app, you'd want to use a real service layer and dependency inversion instead of a static class. Maybe you'd use lazy loading dependencies (as mentioned in a previous post), but let's focus on the logging and auditing for now.

The app works very good, so long as you have very honest tellers and customers. Unfortunately, the CFO of this bank is on the verge of being fired, since millions of dollars have gone missing and no one can figure out why. She hires you, the humble PostSharp expert, and begs for your help in figuring out what's wrong. She wants you to put some code into place to keep records of all transactions and transaction amounts. You could write a bunch of boilerplate logging code and put it in every method in the business logic (only 4 methods in our case, but this would be many many more in a real application). Or, you could write one aspect and apply it to every method in the business logic right away. Since you won't be monkeying around in the actual business logic code, your aspect won't disrupt the app, and is relatively safe to deploy with minimal or no regression testing:

[Serializable]
public class TransactionAuditAttribute : OnMethodBoundaryAspect
{
	private string _methodName;
	private Type _className;
	private int _amountParameterIndex = -1;

	public override bool CompileTimeValidate(MethodBase method)
	{
		if(_amountParameterIndex == -1)
		{
			Message.Write(SeverityType.Warning, "999",
			 "TransactionAudit was unable to find an audit 'amount' in {0}.{1}",
			 _className, _methodName);
			return false;
		}
		return true;
	}

	public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
	{
		_methodName = method.Name;
		_className = method.DeclaringType;

		var parameters = method.GetParameters();
		for(int i=0;i<parameters.Length;i++)
		{
			if(parameters[i].Name == "amount")
			{
				_amountParameterIndex = i;
			}
		}
	}

	public override void OnEntry(MethodExecutionArgs args)
	{
		if (_amountParameterIndex != -1)
		{
			Logger.Write(_className + "." + _methodName + ", amount: "
				+ args.Arguments[_amountParameterIndex]);
		}
	}
}

Note that CompileTimeInitialize is being used to get the method name and parameter names at compile time, to minimize the amount of reflection being used at runtime, and CompileTimeValidate is being used to make sure that there is an ‘amount' parameter to look at. If there isn't, it will generate a compiler warning (you could certainly change this to be an error if you wanted to prevent compilation entirely).

With that aspect in place, and a suitable place to store the auditing data (you could use a database or a logging framework--in this example I'm just using an in-memory collection), your application will start collecting data for the CFO's investigation in an unobtrusive way.

Screenshot of an audit trail

While that investigation is going, you suspect that there other problems with this system: it might not be the most robust of user interfaces, and after talking to the users, you learn that it tends to crash a lot. You could put try/catch blocks in every single UI method to see why it's crashing (this could be quite a lot in a large app). Or, you could just write a single aspect to handle the try/catch logging and recovery. Here's a very simple example:

[Serializable]
public class ExceptionLoggerAttribute : OnExceptionAspect
{
	private string _methodName;
	private Type _className;

	public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
	{
		_methodName = method.Name;
		_className = method.DeclaringType;
	}

	public override bool CompileTimeValidate(MethodBase method)
	{
		if(!typeof(Form).IsAssignableFrom(method.DeclaringType))
		{
			Message.Write(SeverityType.Error, "003",
			 "ExceptionLogger can only be used on Form methods in {0}.{1}",
			 method.DeclaringType.BaseType, method.Name);
			return false;
		}
		return true;
	}

	public override void OnException(MethodExecutionArgs args)
	{
		Logger.Write(_className + "." + _methodName + " - " + args.Exception);
		MessageBox.Show("There was an error!");
		args.FlowBehavior = FlowBehavior.Return;
	}
}

Once again, I'm using CompileTimeInitialize to cut down on the slow runtime Reflection. To use that aspect, I could decorate every method in the UI with it like so:

Attributes applied to methods in a repetitive way

This isn't the worst approach--the exception handling/logging is still separated into its own class, but it's still repetitive and inflexible. Instead, let's just multi-cast out to all the methods like so:

// in AssemblyInfo.cs
[assembly: ExceptionLogger(AttributeTargetTypes = "LoggingAuditing.BankAccountManager")]

If you have more than one class, you could instead set the AttributeTargetTypes to "LoggingAuditing.*" to hit every class in that namespace. Doing it this way means you don't have to put attributes on every single method.

Once all this logging and auditing is in place, it should be fairly obvious to anyone reading the gathered information that two things have gone horribly wrong with the design of this app:

  • Customers are allowed to withdraw negative amounts, and the less honest customers are taking advantage of this!
  • Tellers that process a high volume of transactions make typos from time to time, but there is no checking being done on the input. If a teller enters "$5.19", for instance, decimal.Parse will throw an unhandled exception and crash the application.

With two very simple aspects, you've sussed out two glaring problems with the application, given the business users an audit trail of all transactions, and given the developers on your team an easy way to log and trace exceptions in production. As a consultant, you should recognize that a severely broken application in production like this indicates a deeper cultural problem with the development project team, but by using PostSharp to quickly diagnose these easily fixed problems, you will be on your way to building trust. You can spend this good will on introducing software craftsmanship principles and other bigger changes into the team.

Now, let's look under the hood a bit, and see what code PostSharp is actually generating, and give you some idea of the difference between the starter version and the paid version. Don't panic if you don't totally understand this yet; PostSharp is so easy to use that you might not ever have to open up Reflector to look at the generated code. But let's take a look anyway, just to get some insights into what PostSharp is doing.

Here is the "Credit" method without using PostSharp at all. As you can see, it's exactly what we would expect:

public static void Credit(decimal amount)
{
	Balance += amount;
}

Now here's the "Credit" method after the starter version of PostSharp applies the TransactionAudit aspect. Remember that this code is only in the assembly, and your source code won't change at all.

public static void Credit(decimal amount)
{
	Arguments CS$0$0__args = new Arguments();
	CS$0$0__args.Arg0 = amount;
	MethodExecutionArgs CS$0$1__aspectArgs = new MethodExecutionArgs(null, CS$0$0__args);
	CS$0$1__aspectArgs.Method = <>z__Aspects.m11;
	<>z__Aspects.a14.OnEntry(CS$0$1__aspectArgs);
	if (CS$0$1__aspectArgs.FlowBehavior != FlowBehavior.Return)
	{
		try
		{
			Balance += amount;
			<>z__Aspects.a14.OnSuccess(CS$0$1__aspectArgs);
		}
		catch (Exception CS$0$3__exception)
		{
			CS$0$1__aspectArgs.Exception = CS$0$3__exception;
			<>z__Aspects.a14.OnException(CS$0$1__aspectArgs);
			CS$0$1__aspectArgs.Exception = null;
			switch (CS$0$1__aspectArgs.FlowBehavior)
			{
				case FlowBehavior.Continue:
				case FlowBehavior.Return:
					return;
			}
			throw;
		}
		finally
		{
			<>z__Aspects.a14.OnExit(CS$0$1__aspectArgs);
		}
	}
}

Again, don't panic! That might seem like quite a mess because of the odd names used, but it's really quite simple: the generated code is just wrapping your code (Balance += amount) inside of a try/catch, and sticking in calls to the overrides of the aspect. The only override actually used in this case is the "OnEntry" method (see line 7), but you can see where the other methods (like OnExit, OnSuccess, or OnException) would be called if you decided to override those methods too.

The above code is what's generated by the starter version of PostSharp. It's completely functional and works great, but as you might have noticed, since you're only using the OnEntry method of the aspect, there's a lot of unnecessary code in there (the try-catch loop, etc). For reference, here's what the paid version of PostSharp generates with its optimal code generation:

public static void Credit(decimal amount)
{
	Arguments CS$0$0__args = new Arguments();
	CS$0$0__args.Arg0 = amount;
	MethodExecutionArgs CS$0$1__aspectArgs = new MethodExecutionArgs(null, CS$0$0__args);
	<>z__Aspects.a14.OnEntry(CS$0$1__aspectArgs);
	Balance += amount;
}

The paid version is smart enough to generate only the code that it needs to, and nothing else. If you are writing an application with heavy use of PostSharp aspects, it might be a good idea to use the paid version to help improve overall performance.

Anyway, despite the funny names used in the generated code, I hope that you're getting an idea of what PostSharp is actually doing under the hood, and the potential performance savings you could be gaining with the full version of PostSharp.

Matthew D. Groves is a software development engineer with Telligent, and blogs at mgroves.com.

As one of the core contributors to a compiler for a new language, I often find myself needing to explain new concepts and ideas to other developers. Over time, I've gradually found an approach that tends to work. First, where does the concept fit on the language feature or paradigm map? Second, what is the problem that it is
aimed at, and how are other perhaps more familiar solutions weak? And then -- with that critical foundation laid -- what does the new concept actually do to help?

Recently, I was asked to speak about Aspect Oriented Programming at .Net Community Day in Sweden. I've known about AOP for years and discussed it with developers before, but this was a nice opportunity for me to
spend a while thinking about how best to go about explaining it. So I set about coming up with the AOP answers for my three questions.

The paradigm jigsaw

There are a bunch of titles that we tend to put before the word "programming". "Object Oriented Programming", "Functional Programming", "Declarative Programming" and "Generic Programming" are just some examples. They're all paradigms, but the amount they try to answer differs. The first three I listed -- OOP, FP and DP -- will
happily jostle for pride of place in a language, seeking to be its "core paradigm", and posing a challenge to language designers who see value in all of them. Of course, some languages do decide to just follow a single paradigm: regexes are happily declarative, and Java has admitted little into the language that isn't squarely inside the OO box. However, most of the popular and expressive general purpose languages out there today embrace multiple of these "core paradigms", recognizing that solving every programming task with a single paradigm is like doing every garden task with a lawnmower.

At the same time, there are paradigms that simply seek to deal with a very particular set of issues. Generic programming is one of them: it deals with the situations where we want to use the same piece of code with different types, in a strongly typed way. This idea actually cross-cuts the "core paradigms"; generics are simply
a case of parametric polymorphism, which one finds in functional languages.

The purpose of Aspect-Oriented Programming

This is the kind of place that AOP sits. It's not pitching itself as a successor to -- or even a competitor of -- any of our familiar core paradigms. Instead, it takes a problem and proposes an approach for solving it. So what's the problem?

In any complex code base, there are cross-cutting concerns -- things that we need to do in many places that are incidental to the core logic. For example, logging and exception handling and reporting are generally things that a piece of code does in addition to the task that it really exists to perform. Of course, we factor as much of
the logging and reporting code out as we can, but generally we find ourselves doomed to repeat similar-looking bits of cross-cutting logic in many places. Even if it's just a call to the logger, or a catch block, it ends up duplicated.

Duplicated code is generally a bad sign. For one, it inhibits future refactoring; if we decide to switch logging library, this is now a change in many places. Since we have mentioned the logging library in many places, we have many pieces of our code that are closely coupled to it -- something that goes against our general preference for code that is loosely coupled. We also run into challenges when we want to install new cross-cutting concerns into our software -- there's so many places to change!

Aspect Oriented Programming is aimed at these kinds of challenges. It introduces the concept of join points -- places in our code that we could add some functionality -- and advice -- the functionality that we want to incorporate. It provides a mechanism to write the cross-cutting functionality in one place and have it "inserted" into the join points.

Managing complexity

A common reaction is, "wow, magical", but if we cast our eyes back over programming history, it's really not so surprising. Once upon a time there was just assemblers. Repeating regular sequences of instructions was tiring, so macro systems were created. These "magically" got substituted for a sequence of instructions, with some parametrization thrown in to make them more powerful. A little further on, named and callable subroutines allowed for real re-use of code. We raised the abstraction bar: "you don't have to worry about what this bit of code does, just call it like this". Then came OO. Here things got really magical: invoking one of these method things leaves you with no idea what bit of code is going to be called! It could come from that familiar bit of code you wrote yesterday, or it could come from a subclass that's going to be written in 10 years time.

Over the years, we've evolved ways to manage complexity in software, many of them hanging off increasingly non-linear or loosely coupled flow of control. We've coped with the increasing complexity in our paradigms and programming style, because they more than pay themselves back by decreasing complexity in the software we produce using them. AOP's concept of join points and advice is giving us a little more conceptual overhead in exchange for a more maintainable and less coupled implementation of our cross-cutting concerns.

Looking to the future, I think it's important to remember that where we are with any paradigm today is almost certainly some way from the ideal. We've learned a lot about object oriented programming over the decades that it has existed, and continue to do so. Multiple inheritance has generally been marked down as a bad idea, and the
emergence of traits in Smalltalk (also known as roles in Perl 6) has made some -- myself included -- question whether we'd be better off dropping inheritance altogether in favor of flattening composition.

AOP has only had 15 years of lessons learned so far, and I've no doubt we've got a long road to walk from here. However, that being the case shouldn't stop us from embracing AOP today. After all, the ongoing journey of the object oriented paradigm isn't something that stops us from using it. The critical question is, "does this help me deliver higher quality, more maintainable software" -- and I think there are a bunch of use cases where today's implementations of AOP help us to do so.

About The Author
Jonathan WorthingtonJonathan Worthington is an architect and programming mentor at Edument. He works to help development teams improve their software architecture and work more efficiently, following best practices. He is also one of the core developers of the Rakudo Perl 6 compiler, where his work focuses on the implementation of object oriented language features and the type system. In his free time, he enjoys hiking in the mountains, good beer and curry.