Search code examples
c#-3.0inversion-of-controlextension-methodsdependenciestestability

Do Extension Methods Hide Dependencies?


All,

Wanted to get a few thoughts on this. Lately I am becoming more and more of a subscriber of "purist" DI/IOC principles when designing/developing. Part of this (a big part) involves making sure there is little coupling between my classes, and that their dependencies are resolved via the constructor (there are certainly other ways of managing this, but you get the idea).

My basic premise is that extension methods violate the principles of DI/IOC.

I created the following extension method that I use to ensure that the strings inserted into database tables are truncated to the right size:

public static class StringExtensions
{
    public static string TruncateToSize(this string input, int maxLength)
    {
        int lengthToUse = maxLength;
        if (input.Length < maxLength)
        {
            lengthToUse = input.Length;
        }

        return input.Substring(0, lengthToUse);
    }
}

I can then call my string from within another class like so:

string myString = "myValue.TruncateThisPartPlease.";
myString.TruncateToSize(8);

A fair translation of this without using an extension method would be:

string myString = "myValue.TruncateThisPartPlease.";
StaticStringUtil.TruncateToSize(myString, 8);

Any class that uses either of the above examples could not be tested independently of the class that contains the TruncateToSize method (TypeMock aside). If I were not using an extension method, and I did not want to create a static dependency, it would look more like:

string myString = "myValue.TruncateThisPartPlease.";
_stringUtil.TruncateToSize(myString, 8);

In the last example, the _stringUtil dependency would be resolved via the constructor and the class could be tested with no dependency on the actual TruncateToSize method's class (it could be easily mocked).

From my perspective, the first two examples rely on static dependencies (one explicit, one hidden), while the second inverts the dependency and provides reduced coupling and better testability.

So does the use of extension methods conflict with DI/IOC principles? If you're a subscriber of IOC methodology, do you avoid using extension methods?


Solution

  • I see where you are coming from, however, if you are trying to mock out the functionality of an extension method, I believe you are using them incorrectly. Extension methods should be used to perform a task that would simply be inconvenient syntactically without them. Your TruncateToLength is a good example.

    Testing TruncateToLength would not involve mocking it out, it would simply involve the creation of a few strings and testing that the method actually returned the proper value.

    On the other hand, if you have code in your data layer contained in extension methods that is accessing your data store, then yes, you have a problem and testing is going to become an issue.

    I typically only use extension methods in order to provide syntactic sugar for small, simple operations.