Dependency injection & their Pitfalls*

After I had my dependency injection set up and running, I noticed a shift in my way of developing. I started to be more focused on only one class and their implementation at a time. If I felt the need for another service instance, I just added it to the constructor and would go on coding. I thought that the dependency injection container would take care of how to create the new service for me.

image

This is nothing fancy so far. After coding for straight 20 minutes without any testing in between I decided to test it. I noticed my machine was doing really nothing but burning cpu for a bunch of seconds and quitting then with a StackoverflowException. I had no idea what was going on.

The exception was not really telling too much about the problem. The only thing was a truncated stacktrace. It had something to do with the container trying to create an instance of a service. Without any further information it would be hard to pinpoint this so I decided to search for trace information. I am using Microsoft Prism with the Unity container for inversion of control. So does Unity provide any traces of what is going on? Surprisingly, this is not the case! There is no magic switch.

So I had no choice but removing constructor arguments here and there until I found the root problem. I had managed to create a circular reference:

image

The MSDN is telling me, that it is my responsibility to prevent this and it also warns of endless recursion. Endless recursion always ends with an StackoverflowException.

My solution was simple. I removed the circular reference through removing one reference. It was not used anyway.

*The name of this article is freely leaned on the name of the blog EAI Technologies & their Pitfalls of an ex coworker Winking smile

Posted in C#, coding, dependency injection, Prism | Leave a comment

How to make static legacy code testable

I had the opportunity to work in a team developing and improving a large legacy application. The project had some unit tests already but there was a long way to go in terms of increasing the test coverage.

Many internal services are implemented as a bunch of static methods like so:

static class SeriousService
{
    public static int DoSomething(string value)
    {
        //<side effects here>
        return 17;
    }
}

And the usages of these static classes are all over the place like so:

class SomeModule
{
    public void ExecuteOrder(Order order)
    {
        //...
        SeriousService.DoSomething(order.Name);
        //...
    }
}

image

The challenge was to write a unit test which would test ExecuteOrder() without side effects in SeriousService.

A state-of-the-art application would insert the service through dependency injection into SomeModule. You could provide a mock for the service and you would be ready to write your unittest.

Unluckily, changing the caller or the signature of the callee was no option to me. The chance to introduce incompatibilities somewhere in the huge family of applications and tools was to high.

After some thinking I came up with the idea to extract the functionality out of the static service:

image

The “new” static service endpoint has now a private static reference to the service implementation and all public methods forward there calls to this implementation. The new service implementation is based on an extracted interface. Caller and callee are still unchanged (red rectangle). In code, it looks like so:

interface ISeriousService
{
    int DoSomething(string value);
}

class SeriousServiceImpl : ISeriousService
{
    public int DoSomething(string value)
    {
        //<side effects here>
        return 17;
    }
}

static class SeriousService
{
    private static ISeriousService _seriousService
                            = new SeriousServiceImpl();

    //Static endpoint
    public static int DoSomething(string value)
    {
        return _seriousService.DoSomething(value);
    }
}

Until here, all we have done is to insert another level of indirection. But this enables us to replace the real functionality of the service with a mock:

image

This is possible if the service “endpoint” gets a public method to replace its implementation:

static class SeriousService
{
    private static ISeriousService _seriousService
                            = new SeriousServiceImpl();

    public static void ReplaceServiceImpl(ISeriousService newImpl)
    {
        _seriousService = newImpl;
    }

    //Static endpoint
    public static int DoSomething(string value)
    {
        return _seriousService.DoSomething(value);
    }
}

Having all of this in place you can write your unit test for the module without the fear of any unforseen sideeffects:

[TestFixture]
class SomeModuleTest
{
    [Test]
    public void ExecuteOrder_handles_condition_xyz()
    {
        //Setup
        var service = new Mock<ISeriousService>();
        SeriousService.ReplaceServiceImpl(service.Object);

        //Execute
        new SomeModule().ExecuteOrder(new Order());

        //Asserts here
    }
}

There is one more thing left to be done. Obviously the real instance of SeriousServiceImpl is gone for good after executing the test. So if you want to be able to reuse the current AppDomain for another test you either need to recover it somehow or you have to replace it in every test. I have a nice solution for this as well but this article is already long enough.

So summing up, we saw how to introduce another level of indirection into our architecture. We used it to swap the implementation of a static service as was needed to write unit tests without side effects.

Posted in coding, mocking, unittesting | 1 Comment

String.Split() Kwik-e

While I was cleaning up some legacy code I found an overly complex usage of String.Split() in several places:

var sentence = "Hello World!";
var words = sentence.Split(new char[] { ' ' });

If you take a look at the available overloads on Split() you may miss the params keyword. In fact it isn’t even visible on the overview page:

image

But if you take a closer look on Split(char[]) you will see this:

image

The params keyword tells you that the method accepts any number of arguments of type char. So you could also provide only one, which will simplify the given sample to:

var sentence = "Hello World!";
var words = sentence.Split(' ');
Posted in C#, coding, Kwik-e | 1 Comment