Removing Duplicate Code in Functions
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.







[...] Removing Duplicate Code in Functions - Alex Mueller looks at a few techniques (delegates and AOP) for eliminating duplication of code - examples include logging on start and end of functions. [...]
Damn, Alex.his is one of the coolest techniques I have ever seen. Now I realize I actually need to start using AOP instead of just reading about it.
Nice, man.
Nice post Alex. I do have to say that I prefer the delegate method as it more clearly states your intent.
One problem I have with AOP in general is that the application of an aspect occurs outside the function’s definition. That has always made it hard for developers new to some code to know where to look.
I’m sure one day I’ll find an example of AOP being put to good use beyond the ubiquitous logging example. If anyone knows of such an example please do point me to it.
With the delegate method I might even like to pull that all out in to a method which reads something like RunTestsWithLogging(). Leaving the test methods themselves less noisy.
Thanks for the post, think I’ll go look in to some AOP now!
Hello Alex
Thank you for this wonderful post. I stumbled over the Postsharp project and was being redirected to your nice article. I think I prefer the delegate approach too. But I must admit that I like the AOP approach either, but sometimes it’s just too much magic under the hood.
— begin metapher mode –
It’s almost like having to choose for home security between my best friend or Jack Bauer. Certainly Jack Bauer is the more trained and specialized person for securing my home place than my best friend could ever be but I happen to know my best friend better than Jack Bauer and therefore I have more trust in him
— end metapher mode –
Have a nice day
Thanks for this helpful article. I have a similar problem which perhaps can be solved via AOP. Perhaps you can offer some advice.
Say I have a simple common interface in my library IFoo:
interface IFoo { void doSomething(); }
With multiple subclasses Foo1, Foo2, …, FooN all implementing IFoo differently.
My current approach is to write a single base class Test written against IFoo, and then a test subclass for each implementation of IFoo, which creates an instance of the appropriate type in SetUp.
This works fine, and reworking with AOP would probably be straightforward but might not buy me a great deal.
However, I’ve been asked to support the ability to run from the IDE by right-clicking on a single test function and selecting “Run Test(s)” which I believe is part of the NUnit IDE extension functionality.
Currently this doesn’t work because the only class containing the test function definitions is abstract. I’m having trouble envisaging a way to provide the user with something to click on to run a single invocation of the Test (there are other test framework GUIs but that’s not deemed acceptable).
Do you have any insight on how to make this kind of behavior available ? I was thinking of using AOP and using test subclasses to imply advice, but this still won’t give the user something to click on so now that I’ve written it down, I’m thinking it’s a bit unachievable. Still, I’d be happy for input and this article is in that area.