I’m using PostSharp on a project, with a custom aspect that provides standard handling for authentication and authorisation.

To ensure that all our service methods are properly annotated with our custom aspect (there are only a couple of service calls that shouldn’t have the attribute present) I wrote a unit test:

public void PublicMethods_MustHaveSecurity()
    var facade = typeof(Facade);
    var violatingMethods
        = typeof(IFacade).Assembly.GetExportedTypes()
            .Where(t => t.IsClass)
            .Where(t => facade.IsAssignableFrom(t))
                c => c.GetMethods(
                    BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
                m => m.GetCustomAttributes(
                    typeof(AuthenticatedServiceAttribute), false).Count() == 0)
    var message
        = violatingMethods.Select(m => string.Format("{0}.{1}", m.DeclaringType.Name, m.Name))
            .JoinWith("; ");
    Assert.That(violatingMethods.Count, Is.EqualTo(0), "Found " + message);

Let’s walk through to see how this works.

We find the assembly containing all our service method facades, and from this assembly find all exported types that are classes descending from Facade. From each facade class, we select all the public methods and check each to see if our custom aspect is present, keeping only the methods that are not decorated.

Given the list of violatingMethods, we select the class qualitifed name of each method, joining them all together with “; “.

Easy. Well, easier to read than to write anyway.

There was one final trick required to make this work - by default, PostSharp will remove the aspect attributes after processing. I needed to add a MulticastAttributeUsage attribute to the aspect to configure PostSharp to leave the attribute in place:

[MulticastAttributeUsage(MulticastTargets.Method, PersistMetaData = true)]
public class AuthenticatedServiceAttribute : OnMethodBoundaryAspect

This is just one - very specific - example of what you can do with Linq and a unit test, checking to ensure that a desired convention is correctly applied.


blog comments powered by Disqus
Next Post
Logitech: UX Fail  13 May 2010
Prior Post
What makes a Developer?  01 May 2010
Related Posts
Browsers and WSL  31 Mar 2024
Factory methods and functions  05 Mar 2023
Using Constructors  27 Feb 2023
An Inconvenient API  18 Feb 2023
Method Archetypes  11 Sep 2022
A bash puzzle, solved  02 Jul 2022
A bash puzzle  25 Jun 2022
Improve your troubleshooting by aggregating errors  11 Jun 2022
Improve your troubleshooting by wrapping errors  28 May 2022
Keep your promises  14 May 2022
May 2010