Welcome to the Coach Factor blog. Here you will find all of our ideas on software development. Subscribe at http://blog.nventive.net.
If you haven't read Part 1, Part 2 and Part 3 of this serie, go ahead, we'll wait right here.
In the previous post, we suggested that you can move instance methods that represent overloads to static extension methods.
It's been known for a while that static methods don't do well. They infer with most OO principles and are barely testable. Some will even define those as evil.
When you look at the definition of evil, it is used to indicate acts that are selfish.
Static Methods are selfish in the sense that they keep implementation details for themselves. They take control and keep it. They won't allow you to replace them with a mock version for test purposes. They won't allow their behaviour to be modified without digging into the inner guts and recompiling. They can't be decorated, they can't be proxied, they're selfish.
But can't we have both? The ease and greatness of extension methods without the selfishness and lack of testability of static methods?
Well yes you can... Sort of...
Let's start by looking at an extension method we previously developed:
public static class TypeExtensions
{
public static bool Is<T>(this Type type)
return typeof(T).IsAssignableFrom(type);
}
It contains almost no code but still, it can't be mocked nor replaced.
In order to replace the implementation of this method with another one, we simply need to
1-Extract this method into an interface
public interface ITypeExtensions
bool Is<T>(Type type);
2- Provide a default implementation.
public class DefaultTypeExtensions : ITypeExtensions
public bool Is<T>(Type type)
3- Make sure the extension method delegates to the instance method
public static ITypeExtensions Extensions = new DefaultTypeExtensions();
return Extensions.Is<T>(type);
On the sunny side, we are now able to completely test our extension method implementation. It can also be mocked as we've extracted an interface. It can be replaced or decorated with a Thread-safe version.
On the dark side, you need to set your mock instance to the public static Extensions field in order for existing code to call the mock. It is sort of an indirect dependency.
2008 nVentive. All rights reserved.