Alex Mueller on Software and Technology 
Wednesday, July 30, 2008

The marker interface is an interface that is empty. It does not implement any properties nor methods. It is used to mark the capability of a class as implementing a specific interface at run-time. In languages that do not provide support for associating metadata to a class, this approach can be useful. In C#, metadata attributes are available to apply to a class, and according to the .NET Framework 3.5 Design Guidelines for Developing Class Libraries, marker interfaces should be avoided.

When I first noticed these marker interfaces in project I immediately thought it was a code smell. It just did not seem "right." Why provide an interface that defines nothing? Why provide a marker interface that implements a non-marker interface? Obviously there must be a reason for this?

Two sources encourage me to avoid using marker interfaces and to use attributes in C#. Interface Design and .NET Type Design Guidelines - Interface Design.

There advice is to avoid this...

public interface IFooAssignable {}
 
public class FooAssignableAttribute : IFooAssignable
{
    // ...
}

And to embrace this approach...

[FooAssignable]
public class Foo
{
    // ...
}
 
public class FooAssignableAttribute : Attribute
{
    // ...
}

There appears to be more work involved in writing "good" code.

If I am using "marker" interfaces, I can do this...

if(foo is IFooAssignable)
{
    // ...
}

If I am using attributes, I can do something like this...

object[] attributes = foo.GetType().GetCustomAttributes(false);
 
foreach (string attribute in attributes)
{
    if(attribute == "FooAssignable")
    {
        // ...
    }
}

Or, thanks to Jarod Ferguson's suggestions on using extension methods and LINQ, I could have this...

public static class AttributeExtensions
{
    public static bool IsAttributedAs<T>(this object obj)
    {
        if(obj.GetType().GetCustomAttributes(false).Where(x => x is T).ToList().Count == 1)
            return true;
        return false;
    }
}
 
// Then wherever I want to check for the attribute marker...
if (foo.IsAttributedAs<FooAssignableAttribute>())
{
    // ...
}

At this point, while "marker" interfaces are a code smell to me, I am still on the fence when it comes to using them versus custom attributes. I will more than likely tend to favor the attribute approach, unless I can prove that the cost of reflection is too expensive for my situation. I admit, I will do what I can to omit marker interfaces, perhaps by using some other interface where possible.

What are you doing in situations like this? Can you offer me a more elegant solution?

Wednesday, July 30, 2008 1:01:11 PM (Mountain Standard Time, UTC-07:00) | Comments [0] | Design | Frameworks/Patterns#
Tuesday, April 08, 2008

Duplicate code to me is wrong. Writing duplicate code to me is like using poor grammar. If I am unaware of it, I am none the wiser. However, if I knowingly use poor grammar or duplicate code, I feel bad.

After seeing too many duplications across methods in one or more classes, I decided to investigate a way to remove these. I am always looking to remove duplicate code, even code that shares similarities, I look to refator. Removing duplications is important to adapt more easily to change. When a code change is required, we should only have to make it in one place. The following article will show two relatively simple means to address this code smell, delegates and an Aspect-Oriented approach.

The example I am using in this article is seen below. It is a unit test class, StackFixture class, and it is extremely trivial. This is a typical unit test taken from Test-Driven Development in Microsoft .NET. I have added the logging functionality as an easy means to show how these types of DRY violations can occur. While the duplications in this example deal with logging, they could pertain to other, more complex, functionality as well. The approaches to removing duplications across methods in this article can work with these simple scenarios, as well as more complex ones.

Take for example this sample test case. Each test method logs a message before and after executing the test logic. This violates DRY. We want to keep our test logic in our method, but factor out the duplicate logging. Again, if we were not logging, but doing some repetitive logic, we could factor that out as well.

   1: [TestFixture]
   2: public class StackFixture : AbstractBaseFixture
   3: {
   4:     private Stack stack;
   5:  
   6:     [SetUp]
   7:     public void SetUp()
   8:     {
   9:         stack = new Stack();
  10:     }
  11:  
  12:     [Test]
  13:     public void Empty()
  14:     {
  15:         Log.Info("Starting Empty test");
  16:  
  17:         Assert.IsTrue(stack.IsEmpty);
  18:  
  19:         Log.Info("Ending Empty test");
  20:     }
  21:  
  22:     [Test]
  23:     public void PushOne()
  24:     {
  25:         Log.Info("Starting PushOne test");
  26:  
  27:         stack.Push("first element");
  28:         Assert.IsFalse(stack.IsEmpty, "After Push, IsEmpty should be false.");
  29:  
  30:         Log.Info("Ending PushOne test");
  31:     }
  32:  
  33:     [Test]
  34:     public void Pop()
  35:     {
  36:         Log.Info("Starting Pop test");
  37:  
  38:         stack.Push("first element");
  39:         stack.Pop();
  40:         Assert.IsTrue(stack.IsEmpty, "After Push - Pop, IsEmpty should be true.");
  41:  
  42:         Log.Info("Ending Pop test");
  43:     }
  44:  
  45:     [Test]
  46:     [ExpectedException(typeof(InvalidOperationException))]
  47:     public void PopEmptyStack()
  48:     {
  49:         Log.Info("Starting PopEmptyStack test");
  50:  
  51:         stack.Pop();
  52:  
  53:         Log.Info("Ending PopEmptyStack test");
  54:     }
  55: }

 

Remove Duplications with Delegates

Quite simply, we can remove our method duplications using a delegate, in this case, the System.Action delegate. Thanks to Ayende for helping me understand this option. We create a method, TestMethod (as shown below), and add it to our StackFixture class. The method takes two strings (string beforeMessage and string afterMessage) and the Action delegate, representing the test method logic. We will call this method within our test cases.

   1: public void TestMethod(string beforeMessage, string afterMessage, Action action)
   2: {
   3:     // before
   4:     Log.Info(beforeMessage);
   5:     
   6:     // invoke our method
   7:     action();
   8:     
   9:     // after
  10:     Log.Info(afterMessage);
  11: }

Then, in our tests, we replace the following test method...

   1: [Test]
   2: public void Pop()
   3: {
   4:     Log.Info("Starting Pop test");
   5:  
   6:     stack.Push("first element");
   7:     stack.Pop();
   8:     Assert.IsTrue(stack.IsEmpty, "After Push - Pop, IsEmpty should be true.");
   9:  
  10:     Log.Info("Ending Pop test");
  11: }

With the same method using our delegate approach.

   1: [Test]
   2: public void Pop()
   3: {
   4:     TestMethod("Starting Pop test", "Ending Pop test",
   5:                delegate
   6:                    {
   7:                        stack.Push("first element");
   8:                        stack.Pop();
   9:                        Assert.IsTrue(stack.IsEmpty, "After Push - Pop, IsEmpty should be true.");
  10:                    });
  11: }

We can replace each of our test methods with the same TestMethod using the System.Action delegate. It will then easy to omit our before and after strings replacing them with "action.Method.Name," or some other intelligent logic to determine what to log.

This approach works well, but delegates are often difficult to understand. If this solution suits your needs, make sure the implementation is easily maintainable. What is nice about this approach is how simple it is. There is no need to reference any assemblies outside of the .Net framework, i.e. no third party dependencies.

 

The Aspect-Oriented Approach

Aspect-Oriented Programming (AOP) is an entirely different animal. It certainly deserves more than just a blog post. Please read more about it online. This article will not explain the details of AOP.

If you are reading this, welcome back. I will assume you are now familiar with AOP. There are several options for AOP frameworks. Some frameworks I have used are Spring.net, Castle Project, and PostSharp. The former two provide IoC capabilities as well. I suggest using a well-supported framework, one with community support and frequent updates. Investigate for yourself, there are several nice options available.

 

AOP with Castle DynamicProxy

Hamilton Verissimo put together a good sample using Castle's DynamicProxy. It is a nice, clean implementation.This worked fine for me and would work well in other situations. However, in my scenario, if I were to use this approach, I needed to have each of my test classes extend from MarshalByRef. In addition, I would need to modify the underlying NUnit framework to create my proxies in order to provide advice. Since I could not do the latter, or did not want to investigate, I searched for other AOP options.

The DynamicProxy aproach to solving your AOP needs is a great option. It just did not work in my situation, only because NUnit executes each of my methods. I would need to somehow intercept the creation of my test class, create a proxy of it, and execute the test methods on it.

 

AOP with PostSharp

Gael Fraiteur's PostSharp is a great option for AOP needs. It is extremely clean and easy to use. It is the simplest AOP framework I have used. I suggest watching Gael's video tutorial.

The first thing I needed to do, besides downloading and installing PostSharp, is to add two references to my project, PostSharp.Laos and PostSharp.Public. After that, I create a simple class extending OnMethodInvocationAspect, called LoggingMethodInvocationAspect.

   1: [Serializable]
   2: public sealed class LoggingMethodInvocationAspect : OnMethodInvocationAspect
   3: {
   4:     private ILogger log;
   5:  
   6:     public LoggingMethodInvocationAspect(ILogger logger)
   7:     {
   8:         log = logger;
   9:     {
  10:  
  11:     public override void OnInvocation(MethodInvocationEventArgs eventArgs)
  12:     {
  13:         // before
  14:         log.Info("OnInvocation Before proceed");
  15:  
  16:         // invoke
  17:         eventArgs.Proceed();
  18:  
  19:         // after
  20:         log.Info("OnInvocation After proceed");
  21:     }
  22: }

At this point, all we need to do is apply our aspect on target methods. The "AttributeTargetMembers" attribute can use wildcards. This tells the AOP framework to only intercept those methods in the "MathService" class that start with "Test." Below is the sample where I specify the target assembly, target type (class or classes to intercept), and target methods to intercept. There are many features beyond what I am showing so do further investigation.

   1: [assembly: ClassLibrary.SampleInterfaces.LoggingMethodInvocationAspect(
   2:     AttributeTargetAssemblies = "ClassLibrary.UnitTesting.Sandbox",
   3:     AttributeTargetTypes = "ClassLibrary.UnitTesting.Sandbox.MathService", 
   4:     AttributeTargetMembers = "Test*")]

Finally, my StackFixture class now looks something like this. Notice that the duplicate logging logic is now removed and each test method is prefixed with "Test" in the method name. This is so that PostSharp can filter what methods to intercept.

   1: [assembly: ClassLibrary.SampleInterfaces.LoggingMethodInvocationAspect(
   2:   AttributeTargetAssemblies = "ClassLibrary.UnitTesting.Sandbox",
   3:   AttributeTargetTypes = "ClassLibrary.UnitTesting.Sandbox.MathService", 
   4:   AttributeTargetMembers = "Test*")]
   5:     
   6: [TestFixture]
   7: public class StackFixture
   8: {
   9:     private Stack stack;
  10:  
  11:     [SetUp]
  12:     public void SetUp()
  13:     {
  14:         stack = new Stack();
  15:     }
  16:  
  17:     [TearDown]
  18:     public void TearDown(){}
  19:  
  20:     [Test]
  21:     public void TestEmpty()
  22:     { 
  23:         Assert.IsTrue(stack.IsEmpty); 
  24:     }
  25:  
  26:     [Test]
  27:     public void TestPushOne()
  28:     {
  29:         stack.Push("first element");
  30:         Assert.IsFalse(stack.IsEmpty, "After Push, IsEmpty should be false.");
  31:     }
  32:  
  33:     [Test]
  34:     public void TestPop()
  35:     {
  36:         stack.Push("first element");
  37:         stack.Pop();
  38:         Assert.IsTrue(stack.IsEmpty, "After Push - Pop, IsEmpty should be true.");
  39:     }
  40:  
  41:     [Test]
  42:     [ExpectedException(typeof(InvalidOperationException))]
  43:     public void TestPopEmptyStack()
  44:     {
  45:         stack.Pop();
  46:     }
  47: } 

The end result, a StackFixture test class with duplicate logging logic removed. The PostSharp AOP framework post-processes the compiled assembly and inserts itself, easily providing points of interception.

The PostSharp approach does involve a third-party dependency, but I feel like it is cleaner than the delegate approach. Gael informed me future versions of PostSharp will provide a more configurable solution than adding the [assembly ...] reference for the aspects, perhaps an XML configuration option. This can be done today, but involves some work.

Whether you use delegates, AOP, or some other approach, remove duplicate code wherever possible. I am happy to use either approach in my projects. There are tradeoffs to either solution, so investigate for yourself.

Tuesday, April 08, 2008 9:04:04 PM (Mountain Standard Time, UTC-07:00) | Comments [0] | Design | Frameworks/Patterns | Technology | Tools#
Tuesday, April 01, 2008
Craig Neuwirt recently started a blog focused on NHibernate, as mentioned by Ayende. NHibernate is an ORM tool I have used on current and past projects and it is something I feel I would like I want to study further. So far, Craig is walking us through NHibernate from the ground-up, with the latest and greatest. I anticipate this being an informative blog to follow.

The NHibernate FAQ
Craig Neuwirt
Hibernating Rhinos

Tuesday, April 01, 2008 8:25:09 AM (Mountain Standard Time, UTC-07:00) | Comments [0] | Design | Frameworks/Patterns | Technology | Tools#
Friday, March 14, 2008