Archive for the 'C#' Category

Refactoring To Functional Code

In my previous post I explained that some problems are better suited to a functional approach than traditional, imperative code. I showed an example of a problem that suits a functional approach and demonstrated turning several lines of imperative code with nested for-each loops and if-statements into a single line of functional code. Paul Harrington posted a comment asking what individual steps I took to refactor the code. Here’s my explanation of the refactoring:

First, here is the original, imperative method.

public int[] Translate(string word)
{
    ArrayList numbers = new ArrayList();

    foreach (char character in word)
    {
        foreach(KeyValuePair<int, char[]> key in keys)
        {
            foreach(char c in key.Value)
            {
                if(c == character)
                {
                    numbers.Add(key.Key);
                }
            }
        }
    }

    return (int[]) numbers.ToArray(typeof (int));
}

As you can see, it takes some effort to determine what’s really going on. From this code we can determine that:

For each character in a word, select the first key in the list of keys that contains the character and add it to an array of numbers to return.

Now, lets express the statement above as functional code:

To select each character in a word, we need to convert the string to an array of characters. The LINQ Select method projects each element of a sequence into a new form. In this case, a string translates to a sequence of characters:

IEnumerable<char> characters = word.Select(c => c);

For each character, we need to find the corresponding key that contains the character. The First method returns the first element of a sequence:

int key = keys.First().Key;

In our case we need the first key in the list of keys that contains the character. The First method has an overload that returns the first element in a sequence that satisfies a specified condition.  To specify our condition we use the Contains method, which determines whether a sequence contains a specified element:

char c = 'a';
int number = keys.First(k => k.Value.Contains(c)).Key;

When we combine the code that selects each character with the code that gets the first key containing the character, we end up with this:

IEnumerable<int> numbers = word.Select(c =>
        keys.First(k => k.Value.Contains(c)).Key);

Finally, we use the ToArray method to return an array of type int. Now we have our final, refactored method:

public int[] Translate(string word)
{
    return word.Select(c =>
        keys.First(k => k.Value.Contains(c)).Key).ToArray();
}

I hope this helps to explain the steps I took to refactor imperative code to functional code. You can get really clever with functional code, but remember, readability is what’s most important. Sometimes it’s best to stick with good old-fashioned for-loops and if-statements, but for some problems, like above, a functional approach can lead to more readable, clean and concise code.

An Example of Functional vs Imperative Programming in C#

Last week I went to a talk presented by Mike Wagg and Mark Needham from ThoughtWorks on Mixing Functional and Object-Oriented Approaches to Programming in C#. Mike and Mark discussed using a functional approach with LINQ to solve problems in C#.

I have come to realise lately that some problems are much better suited to a functional approach than traditional imperative programming. Many problems that involve selecting, filtering or performing actions on a list of items are best suited to functional programming, which can significantly reduce the amount of code required to solve the problem.

Here is a simple example of a problem that is best solved with a functional rather than an imperative approach.

Some businesses advertise their phone number as a word, phrase or combination of numbers and alpha characters. This is easier for people to remember than a number. You simply dial the numbers on the keypad that correspond to the characters. For example, “1-800 FLOWERS” translates to 1-800 3569377.

We will write a simple program that translates a word into a list of corresponding numbers.

phone-keypad

First, let’s start with a dictionary that contains each number and the corresponding characters:

private readonly Dictionary<int, char[]> keys =
            new Dictionary<int, char[]>()
                {
                    {1, new char[] {}},
                    {2, new[] {'a', 'b', 'c'}},
                    {3, new[] {'d', 'e', 'f'}},
                    {4, new[] {'g', 'h', 'i'}},
                    {5, new[] {'j', 'k', 'l'}},
                    {6, new[] {'m', 'n', 'o'}},
                    {7, new[] {'p', 'q', 'r', 's'}},
                    {8, new[] {'t', 'u', 'v'}},
                    {9, new[] {'w', 'x', 'y', 'z'}},
                    {0, new[] {' '}},
                };

Next, we create a Translate method that takes a word and returns an array of corresponding numbers.

With a traditional, imperative approach, we would use for-each loops and if-statements to iterate through characters and populate an array of matching numbers:

public int[] Translate(string word)
{
    ArrayList numbers = new ArrayList();

    foreach (char character in word)
    {
        foreach(KeyValuePair<int, char[]> key in keys)
        {
            foreach(char c in key.Value)
            {
                if(c == character)
                {
                    numbers.Add(key.Key);
                }
            }
        }
    }

    return (int[]) numbers.ToArray(typeof (int));
}

Alternatively, with a functional approach we can use LINQ to select elements from the dictionary and transform the output to an array of matching numbers:

public int[] Translate(string word)
{
    return word.Select(c => 
        keys.First(k => k.Value.Contains(c)).Key).ToArray();
}

And there you have it. Several lines of nested for-each loops replaced with a single line of succinct functional code. Much nicer!

Creating a Simple IoC Container

Inversion of Control (IoC) is a software design principle that describes inverting the flow of control in a system, so execution flow is not controlled by a central piece of code. This means that components should only depend on abstractions of other components and are not be responsible for handling the creation of dependent objects. Instead, object instances are supplied at runtime by an IoC container through Dependency Injection (DI).

IoC enables better software design that facilitates reuse, loose coupling, and easy testing of software components.

At first IoC might seem complicated, but it’s actually a very simple concept. An IoC container is essentially a registry of abstract types and their concrete implementations. You request an abstract type from the container and it gives you back an instance of the concrete type. It’s a bit like an object factory, but the real benefits come when you use an IoC container in conjunction with dependency injection.

An IoC container is useful on all types of projects, both large and small. It’s true that large, complex applications benefit most from reduced coupling, but I think it’s still a good practice to adopt, even on a small project. Most small applications don’t stay small for long. As Jimmy Bogard recently stated on Twitter: “the threshold to where an IoC tool starts to show its value is usually around the 2nd hour in the life of a project”.

There are many existing containers to choose from. These have subtle differences, but all aim to achieve the same goal, so it’s really a matter of personal taste which one you choose. Some common containers in .NET are:

While I recommended using one of the containers already available, I am going to demonstrate how easy it is to implement your own basic container. This is primarily to show how simple the IoC container concept is. However, there might be times when you can’t use one of the existing containers, or don’t want all the features of a fully-fledged container. You can then create your own fit-for-purpose container.

Using Dependency Injection with IoC

Dependency Injection is a technique for passing dependencies into an object’s constructor. If the object has been loaded from the container, then its dependencies will be automatically supplied by the container. This allows you to consume a dependency without having to manually create an instance. This reduces coupling and gives you greater control over the lifetime of object instances.

Dependency injection makes it easy to test your objects by allowing you to pass in mocked instances of dependencies. This allows you to focus on testing the behaviour of the object itself, without depending on the implementation of external components or services.

It is good practice to reduce the number of direct calls to the container by only resolving top-level objects. The rest of object-graph will be resolved through dependency injection. This also prevents IoC-specific code from becoming scattered throughout the code base, making it easy switch to a different container if required.

Implementing a Simple IoC Container

To demonstrate the basic concepts behind IoC containers, I have created a simple implementation of an IoC container.

Download the source and sample code here

This implementation is loosely based on RapidIoc, created by Sean McAlindin. It does not have all the features of a full IoC container, however, it should be enough to demonstrate the main benefits of using a container.

public class SimpleIocContainer : IContainer
{
    private readonly IList<RegisteredObject> registeredObjects = new List<RegisteredObject>();
 
    public void Register<TTypeToResolve, TConcrete>()
    {
        Register<TTypeToResolve, TConcrete>(LifeCycle.Singleton);
    }
 
    public void Register<TTypeToResolve, TConcrete>(LifeCycle lifeCycle)
    {
        registeredObjects.Add(new RegisteredObject(typeof (TTypeToResolve), typeof (TConcrete), lifeCycle));
    }
 
    public TTypeToResolve Resolve<TTypeToResolve>()
    {
        return (TTypeToResolve) ResolveObject(typeof (TTypeToResolve));
    }
 
    public object Resolve(Type typeToResolve)
    {
        return ResolveObject(typeToResolve);
    }
 
    private object ResolveObject(Type typeToResolve)
    {
        var registeredObject = registeredObjects.FirstOrDefault(o => o.TypeToResolve == typeToResolve);
        if (registeredObject == null)
        {
            throw new TypeNotRegisteredException(string.Format(
                "The type {0} has not been registered", typeToResolve.Name));
        }
        return GetInstance(registeredObject);
    }
 
    private object GetInstance(RegisteredObject registeredObject)
    {
        if (registeredObject.Instance == null || 
            registeredObject.LifeCycle == LifeCycle.Transient)
        {
            var parameters = ResolveConstructorParameters(registeredObject);
            registeredObject.CreateInstance(parameters.ToArray());
        }
        return registeredObject.Instance;
    }
 
    private IEnumerable<object> ResolveConstructorParameters(RegisteredObject registeredObject)
    {
        var constructorInfo = registeredObject.ConcreteType.GetConstructors().First();
        foreach (var parameter in constructorInfo.GetParameters())
        {
            yield return ResolveObject(parameter.ParameterType);
        }
    }
}

The SimpleIocContainer class has two public operations: Register and Resolve.

Register is used to register a type with a corresponding concrete implementation. When type is registered, it is added to a list of registered objects.

Resolve is used to get an instance of a type from the container. Depending on the Lifecycle mode, a new instance is created each time the type is resolved (Transient), or only on the first request with the same instance passed back on subsequent requests (Singleton).

Before a type is instantiated, the container resolves the constructor parameters to ensure the object receives its dependencies. This is a recursive operation that ensures the entire object graph is instantiated.

If a type being resolved has not been registered, the container will throw a TypeNotRegisteredException.

Using the Simple IoC Container with ASP.NET MVC

Now I am going to demonstrate using the container by creating a basic order processing application using ASP.NET MVC.

First we create a custom controller factory called SimpleIocControllerFactory that derives from DefaultControllerFactory. Whenever a page is requested, ASP.NET calls GetControllerInstance to get an instance of the page controller. We can then pass back an instance of the controller resolved from our container.

public class SimpleIocControllerFactory : DefaultControllerFactory
{
    private readonly IContainer container;
 
    public SimpleIocControllerFactory(IContainer container)
    {
        this.container = container;
    }
 
    protected override IController GetControllerInstance(Type controllerType)
    {
        return container.Resolve(controllerType) as Controller;
    }
}

We now need to set SimpleIocControllerFactory as the current controller factory in the global Application_Start handler.

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        var container = new SimpleIocContainer();
 
        BootStrapper.Configure(container);
 
        ControllerBuilder.Current.SetControllerFactory(new SimpleIocControllerFactory(container));
    }
}

In order for the SimpleIocControllerFactory to resolve an instance of the OrderController, we need to register the OrderController with the container.

Here I have created a static Bootstrapper class for registering types with the container.

public static class BootStrapper
{
    public static void Configure(IContainer container)
    {
        container.Register<OrderController, OrderController>();
    }
}

The controllers do not contain state, therefore we can use the default singleton lifecycle to create an instance of the controller only once per request.

When we run the application, the OrderController should be resolved and the page will load.

It is worth noting that the controller factory should be the only place we need to explicitly resolve a type from the container. The controllers are top-level objects and all our other objects stem from these. Dependency Injection is used to resolve dependencies down the chain.

To place an order we need to make a call to OrderService from the controller. We inject a dependency to the order service by passing the IOrderService interface into the OrderController constructor.

public class OrderController : Controller
{
    private readonly IOrderService orderService;
 
    public OrderController(IOrderService orderService)
    {
        this.orderService = orderService;
    }
 
    public ActionResult Create(int productId)
    {
        int orderId = orderService.Create(new Order(productId));
 
        ViewData["OrderId"] = orderId;
 
        return View();
    }
}

When we build and run the application we should get an error: “The type IOrderService has not been registered”. This means the container has tried to resolve the dependency, but the type has not been registered with the container. So we need to register IOrderService and its concrete implementation, OrderService, with the container.

public static class BootStrapper
{
    public static void Configure(IContainer container)
    {
        container.Register<OrderController, OrderController>();
        container.Register<IOrderService, OrderService>();
    }
}

The OrderService in turn has a dependency on IOrderRepository which is responsible for inserting the order into a database.

public class OrderService : IOrderService
{
    private readonly IOrderRepository orderRepository;
 
    public OrderService(IOrderRepository orderRepository)
    {
        this.orderRepository = orderRepository;
    }
 
    public int Create(Order order)
    {
        int orderId = orderRepository.Insert(order);
        return orderId;
    }
}

As the OrderService was resolved from the container, we simply need to register an implementation for IOrderRepository for OrderService to receive its dependency.

public static class BootStrapper
{
    public static void Configure(IContainer container)
    {
        container.Register<OrderController, OrderController>();
        container.Register<IOrderService, OrderService>();
        container.Register<IOrderRepository, OrderRepository>();
    }
}

Any further types are that required simply need to be registered with the container then passed as an argument on the constructor.

Most full-featured IoC containers support some form of auto-registration. This saves you from having do to a lot of one-to-one manual component mappings.

I hope I have demonstrated that IoC containers are not magic. They are in fact a simple concept that, when used correctly, can help to create flexible, loosely-coupled applications.

The War On Nulls

As .NET developers, we’ve all seen this exception hundreds of times: “System.NullReferenceException – Object reference not set to an instance of an object”. In .NET, this exception occurs when trying to access a reference variable with a null value. A null value means the variable does not hold a reference to any object on the heap. It is one of the most frustrating and prolific errors that we programmers encounter. But it needn’t be this way! We can prevent this error by following a few simple rules. But first, a little history…

The null reference was invented by Tony Hoare, inventor of QuickSort, one of the world’s most widely used sorting algorithms. In this introduction to his talk at QCon 2009, Tony describes the impact the null reference has had on software:

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. In recent years, a number of program analysers like PREfix and PREfast in Microsoft have been used to check references, and give warnings if there is a risk they may be non-null. More recent programming languages like Spec# have introduced declarations for non-null references. This is the solution, which I rejected in 1965.

So obviously null references have caused quite a lot of damage. But neither Tony or null references are to blame. It’s the careless use of null references that has made them as damaging and prolific as they are.

I can’t think of a single reason why you would need to use null references as part of your system design. Here are some tips for preventing null references in your system.

Never use null references as part of the design

Business logic should not be based around testing for null references. If an object requires an empty state, be explicit about it by creating an empty representation of the object. You can then check if the object is in an empty state by comparing the current instance to an empty instance.

Here is an example of some code that uses a generic interface called ICanBeEmpty to support an empty representation of a Customer object. An extension method called HasValue() allows us to check if an object represents an empty instance.

public class Customer : ICanBeEmpty<Customer>
{
    private int id;
    private string name = string.Empty;
    //...
 
    public bool Equals(Customer other)
    {
        return this.id == other.id;
    }
 
    public static Customer Empty
    {
        get { return new Customer(); }
    }
 
    Customer ICanBeEmpty<Customer>.Empty
    {
        get { return Empty; }
    }
}
 
public interface ICanBeEmpty<T> : IEquatable<T>
{
    T Empty { get; }
}
 
public static class Extensions
{
    public static bool HasValue<T>(this ICanBeEmpty<T> obj)
    {
        return obj.Equals(obj.Empty);
    }
}

Don’t accept null references as parameters

Guard statements are often used to check for null references in methods. If you design your system not to pass nulls, you won’t need guards to check for null in your methods. But when you can’t guarantee input to your public methods, then you need to be defensive about null references.

Don’t return null references

A call to a method or property should never return a null reference. Instead, return an empty representation of an object, or throw an exception if a non-empty value is expected.

Fail fast if a null reference is detected

Design-by-contract technologies, such as Spec#, have declarations that can check for null references at compile time. You can also use an aspect-oriented programming (AOP) solution, such as PostSharp, to create custom attributes that ensures an exception is thrown if any null references are passed in, or returned by a method at runtime. By throwing an exception as soon as a null reference is detected, we can avoid hunting through code to find the source of a null reference.

public class CustomerRepository
{
    [DoesNotReturnNull]
    public Customer GetCustomer(int id)
    {
        //...
        return Customer.Empty;
    }
 
    [DoesNotAcceptNull]
    public void SaveCustomer(Customer customer)
    {
        if (customer.HasValue())
        {
            //...
        }
    }
}

Wrap potential sources of null references

If you are using a third-party service or component where you might receive a null reference, then wrap the call in a method that handles any null references to ensure they don’t leak into the rest of the system.

Always ensure object members are properly instantiated

All object members should be instantiated when an object is created. Be careful with strings in C#, as these are actually reference types. Always set string variables to a default value, such as string.Empty.

Nullable value types are ok

The nullable value types introduced in C# 2.0, such as int? and DateTime?, are better at handling null references as you have to explicitly cast them to a non-null value before accessing them. Be careful with using the Value property on a nullable type without first checking if the variable has a non-null value using the HasValue property. You can use GetValueOrDefault to return a default value if the variable is null.

By limiting the use of null references and not letting them leak into other parts of the system, we can prevent the troublesome NullReferenceException from ruining our day.

User Interface Code And The Open/Closed Principal

The Open/Closed Principal (OCP) is a fundamental object-oriented design principal that states:

“Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.”

This means that we should be able to add new behavior to a software entity without altering its code.

Most UI code I have seen, including Model-View-Presenter (MVP) and Model-View-Controller (MVC) implementations, clearly violate the open/closed principal.

When developing UI code, we tend to create presentation classes in terms of views, or sections of the UI. To add new behavior to the UI, we need to modify these presentation classes. This increases the risk of breaking existing functionality.

UI development can be notoriously complex because of the many interactions and state changes that can occur. To manage this complexity we should ensure that our classes have only one reason to change.

Instead of grouping presentation classes into visible sections of the UI, maybe we should be creating a series of discrete presentation behaviors that react to events raised from the view.

These behaviors can be added and removed without affecting other behaviors on the page.

Behavior-Driven Development (BDD) advocates creating tests based on individual behaviors, so why not create our presentation classes in the same way? The tests then correspond directly to a single discrete unit, rather than a behavior that occurs within a larger structure, e.g. a presenter class.

Each behavior has a name that describes the behavior it represents. Using a descriptive name provides instant documentation of the UI behavior. It should be easy for someone to understand what the UI does simply by looking at the behavior names. If a problem occurs, it should be easy to identify and isolate the affected behavior.

Implementing Presentation Behaviors

I have created a simple music finder application that demonstrates an implementation of presentation behaviors.

Download the sample code here.

The sample application contains a single page, represented by an IFindMusicView interface. The behaviors respond to events raised by this View and update the View accordingly.

A typical behavior can be defined as:

Given… a particular scenario

When… an event occurs

And… all conditions have been met

Then… do something

And… do something else

Each behavior is implemented as a class that derives from a base class with an IBehavior interface. This interface contains two methods: When() and Then().

The When() method contains code that registers the behavior with a certain event on the page. The Then() method contains the code that responds to the event if all conditions have been met. The “Given” aspect is implemented by the class constructor, which takes the view and any associated dependencies.

   1: public class when_song_list_is_empty_disable_select_button : FindMusicBehavior
   2: {
   3:     public when_song_list_is_empty_disable_select_button(IFindMusicView view)
   4:         : base(view)
   5:     {
   6:     }
   7: 
   8:     public override void When()
   9:     {
  10:         View.AfterSongsLoaded += (sender, e) => Then();
  11:     }
  12: 
  13:     public override void Then()
  14:     {
  15:         View.IsSelectButtonEnabled = View.SongsList.Count > 0;
  16:     }
  17: }

 

The behaviors are instantiated by the View, but an Inversion Of Control container could be used to register the behaviors at run-time. The View then wouldn’t need to know anything about the behaviors that are implemented for it. We could then drop-in and drop-out behaviors without needing to change the existing code.

Further Considerations

Although this is an interesting concept, I am yet to implement it on a large-scale application. There are several areas I need to investigate further, such as:

  1. Can one behavior extend the functionality of another behavior?
  2. Can parallel behaviors remain independant from one another?
  3. How does this work with MVC frameworks? Are the behaviors triggered by actions?
  4. How well does this scale?

Feedback

Does this concept make sense? Does it sound practical? Could it potentially solve some of the issues we face with developing complex UI code? Any feedback would be greatly appreciated.

Enjoy!

Legacy Code Can Be Fun!

No, I’m not being ironic; I’m actually enjoying working with legacy code!

I have recently inherited a large, legacy code-base. There are hardly any tests and it’s full of dependencies between components. The application is critical to the day-to-day operation of the business and requires ongoing feature additions, support and maintenance.

By “legacy code”, I am referring to the definition as “code without tests and in need of refactoring”. This is described by Michael Feathers in his excellent book Working Effectively with Legacy Code. This post uses techniques from this book. If you are working with a legacy code base, buy this book! It will make your life much easier.

As developers, most of us have had to endure the frustration of working with code that is unclear and untested (if you haven’t, you don’t know what you’re missing ;-). It can be painful having to make changes without knowing the affect the change could have on the application. We usually apply Change-and-Pray Development, that often results in hard-to-find problems slipping through to production. Over time, constant tacking-on of changes further degrades the quality of the code-base and can result in a Big Ball of Mud.

But fear not, there is a way to make changes to legacy code much easier, and – dare I say, fun! Continuous refactoring and testing can help to turn a bug-ridden, untested and tangled application into a slick, streamlined code-base that just gets better over time.

Introducing Changes To Legacy Code

One of the most difficult things about working with legacy code is introducing changes. Without tests to back us up, it is hard to know if a change has worked and hasn’t broken anything unexpectedly.

For this demonstration, I have created a sample class that reflects some common issues when introducing changes to legacy code. The code is intentionally simple to clarify the refactoring. Real-world legacy code is not usually so simple, but these techniques still apply.

Here we have a DocumentManager class.

public class DocumentManager
{
    public static Document GetDocument(int documentId)
    {
        DocumentDAL documentDAL = new DocumentDAL();
        Document document = documentDAL.Get(documentId);
        if (document != null && !File.Exists(document.Path))
        {
            throw new FileNotFoundException("Document file was not found");
        }
        return document;
    }
    public static List<Document> GetAllDocuments()
    {
        DocumentDAL documentDAL = new DocumentDAL();
        List<Document> documents = documentDAL.List();
        foreach (Document doc in documents)
        {
            if (doc != null && !File.Exists(doc.Path))
            {
                throw new FileNotFoundException("Document file was not found");
            }
        }
        return documents;
    }
    public static void SaveDocument(Document document)
    {
        File.WriteAllText(document.Path, document.Contents);
        DocumentDAL documentDAL = new DocumentDAL();
        documentDAL.Save(document);
    }
    public static void DeleteDocument(int documentId)
    {
        Document document = GetDocument(documentId);
        DocumentDAL documentDAL = new DocumentDAL();
        documentDAL.Delete(document);
        File.Delete(document.Path);
    }
    public static string GetFileName(Document document)
    {
        return Path.GetFileName(document.Path);
    }
}

The purpose of this class is to manage the persistence of documents to a database and file system.

I have come across this type of class many times; it is mostly composed of static methods that call an underlying data access layer. The class is doesn’t have any unit tests and contains direct calls to the file system and a data access class.

My goal is to add some validation code into the Save method of the DocumentManager class and to create unit tests to verify the new functionality.

Firstly, I’m going to create a test harness so I know my changes won’t adversely affect the existing functionality.

Creating a Test Harness

Creating a test harness allows us to make changes while ensuring the code still functions as expected.

Let’s create a new test fixture called DocumentManagerTests.

[TestFixture]
public class DocumentManagerTests
{
}

Instantiating the Class

Now that we have a test fixture in place, let’s create a test that instantiates the class we want to test.

[Test]
public void Can_Create_Instance_Of_DocumentManager()
{
    DocumentManager documentManager = new DocumentManager();
    Assert.That(documentManager, Is.InstanceOfType(typeof(DocumentManager)), "Should create an instance of DocumentManager");
}

Our code doesn’t compile, as DocumentManager is a static class and can’t be instantiated. We could just test the members of the static class, but we need an instance so any dependencies can be passed into the constructor. We will come to this shortly, but for now, let’s remove the static keyword from the class declaration so we can instantiate the class.

public class DocumentManager
{ ...

After making the class non-static our test compiles and passes! The assertion isn’t very meaningful, but at least we know we can instantiate the class without an error.

Breaking Dependencies

The reason legacy code seems difficult to test, is that it often contains internal calls to other components or sub-systems. This makes it difficult to isolate a piece of code for testing.

So why break dependencies and not just test everything? Well, firstly you end up testing the integration between components, rather than a single unit of code. Calling external components can cause our tests to run slowly, or to fail due to an problem with a sub-system.

To test the Save method in isolation, we need to extract calls to the DocumentDAL and File classes.

These are fairly safe structural refactorings, so we should be able to make the changes without affecting functionality.

To remove the dependency on the DocumentDAL class in the Save method, we can use a technique called Dependency Injection.

Dependency Injection

Dependency Injection involves passing a reference to the dependent object into the class constructor. Here, we can use an Extract Interface refactoring to decouple the DocumentDAL implementation from its interface. Using an interface allows us to provide a mock implementation for testing.

public class DocumentDAL : IDocumentDAL
{ ...

We can now “inject” the dependency into the DocumentManager constructor.

public class DocumentManager
{
    private readonly IDocumentDAL documentDAL;
    public DocumentManager(IDocumentDAL documentDAL)
    {
        this.documentDAL = documentDAL;
    } ...

Our test doesn’t compile, as we need to pass an implementation of IDocumentDAL into the constructor. I am using Rhino Mocks to mock an IDocumentDAL implementation.

[Test]
public void Can_Create_Instance_Of_DocumentManager()
{
    MockRepository mocks = new MockRepository();
    IDocumentDAL documentDAL = mocks.CreateMock<IDocumentDAL>();
    DocumentManager documentManager = new DocumentManager(documentDAL);
    Assert.That(documentManager, Is.InstanceOfType(typeof(DocumentManager)), "Should create an instance of DocumentManager");
}

To remove the Save method’s dependency on the file system, we can use another dependency-breaking technique called Subclass and Override Method.

Subclass and Override Method

First, we use Extract Method to move call to the file system into a separate virtual method.

protected virtual void WriteFile(Document document)
{
    File.WriteAllText(document.Path, document.Contents);
} 

We need to change the Save method to call the new WriteFile method. Because WriteFile is an instance method, we need to make the Save method non-static. Note that any code that calls this method will also need to be changed to use the non-static method.

 

public void SaveDocument(Document document)
{
    WriteFile(document);

    DocumentDAL documentDAL = new DocumentDAL();

    documentDAL.Save(document);
}

Now we can create a subclass of DocumentManager called TestingDocumentManager and override the WriteFile method. This allows us to stub-out the calls to the file system by the Save method for use in our tests.

public class TestingDocumentManager : DocumentManager
{
    public TestingDocumentManager(IDocumentDAL documentDAL)
        : base(documentDAL)
    {
    }
    protected override void WriteFile(Document document)
    {
    }
}

Next, we update our test to use the TestDocumentManager with the overridden WriteFile method.

[Test]
public void Can_Create_Instance_Of_DocumentManager()
{
    MockRepository mocks = new MockRepository();
    IDocumentDAL documentDAL = mocks.CreateMock<IDocumentDAL>();
    DocumentManager documentManager = new TestingDocumentManager(documentDAL);
    Assert.That(documentManager, Is.InstanceOfType(typeof(DocumentManager)), "Should create an instance of DocumentManager");
}

Ideally, we could remove the dependency on the file system altogether by injecting an interfaced wrapper for the File class, but that would distract us from the focus of our test. Subclass and Override Method is a very useful technique for quickly getting legacy code under test. We can refactor the code at a later time if required.

Testing the Method

To test the Save method we need to remove the instantiation of DocumentDAL and use the field that was set in the constructor.

 

public void SaveDocument(Document document)
{
    WriteFile(document);

    documentDAL.Save(document);
}

Now we can test the functionality of the Save method.

[Test]
public void Can_Save_Document()
{
    MockRepository mocks = new MockRepository();
    IDocumentDAL documentDAL = mocks.CreateMock<IDocumentDAL>();
    DocumentManager documentManager = new TestingDocumentManager(documentDAL);
    Document document = TestHelper.GetDocument();
    Expect.Call(() => documentDAL.Save(document));

    mocks.ReplayAll();
    documentManager.SaveDocument(document);
    mocks.VerifyAll();
}

Running this test shows us that the behaviour of Save is working as expected. It provides a safety net for making further changes. If a change affects the core behaviour of the Save method, this test should fail.

Making the Changes

Now that we have a test harness in place, we can implement our new changes using Test Driven Development (TDD).

First, we write a test to verify the changes we want to make.

[Test]
public void Cannot_Save_Invalid_Document()
{
    MockRepository mocks = new MockRepository();
    IDocumentDAL documentDAL = mocks.CreateMock<IDocumentDAL>();
    DocumentManager documentManager = new TestingDocumentManager(documentDAL);
    Document document = TestHelper.GetInvalidDocument();
    try
    {
        documentManager.SaveDocument(document);
        Assert.Fail("Should throw an exception for invalid document");
    }
    catch(Exception ex)
    {
        Assert.That(ex, Is.InstanceOfType(typeof(ValidationException)), "Should throw a ValidationException");
    }
}

The code compiles and the test is failing as expected. We now need to implement the code to make the test pass.

public void SaveDocument(Document document)
{
    if(!document.IsValid)
    {
        throw new ValidationException();
    }
    WriteFile(document);
    documentDAL.Save(document);
}

The test passes! We now run all the tests to ensure our change hasn’t broken the existing functionality.

Refactoring

With our tests passing, we can now clean things up a bit. We are free to make changes on any code that has been tested.

We could also take the time to further improve the design of the DocumentManager class, such as separating the File Access responsibilities into another class. The amount of refactoring you do depends on how much time you have. If you can spend some time tidying things up around the code you have changed, the better the code will be for the next person who needs to change it. You don’t have to do everything at once. Generally, code that is changed often should become continuously refactored and improved over time.

Summary

This is just one of many techniques you can use to refactor and test legacy code. Many more examples can be found in Working Effectively with Legacy Code. This has been a very simple example, but I have used these same techniques to make big changes to some very dodgy pieces of code.

Refactoring and testing legacy code can help to improve a legacy code-base over time. It feels like you’re writing new code, rather than just tacking onto existing code. It is also a great feeling walking away from implementing a change, knowing that the surrounding code is now cleaner and more robust than before.

Implementing The Circuit Breaker Pattern In C# – Part 2

In my previous post, I discussed an implementation of The Circuit Breaker Pattern as described in Michael T. Nygard’s book, Release It! Design and Deploy Production-Ready Software. In this post, I will talk about several additions and improvements I have made to the initial implementation.

Service Level

The Circuit Breaker Pattern contains a failure count that keeps track of the number of consecutive exceptions thrown by an operation. When the failure count reaches a threshold, the circuit breaker trips. If an operation succeeds before the failure threshold is reached, the failure count is reset to zero. This works well if the service outage causes multiple consecutive failures, but if the threshold is set to 100 and the service fails 99 times, then one operation succeeds, the failure count is reset to 0, even though there is obviously a problem with the service that should be handled.

To deal with intermittent service failures, I have implemented a “service level” calculation. This indicates the ratio of successful operations to failed operations, expressed as a percentage. For example, if the circuit breaker has a threshold of 100 and an operation fails 50 times, then the current service level is 50%. If the service recovers and 25 operations succeed, then the service level will be 75%. The circuit breaker will not completely reset after a single successful operation. Each successful operation increments the service level, while each failed operation decrements the service level. Once the service level reaches 0%, i.e. the ratio of failed operations over successful ones have reached the threshold, the circuit trips.

A ServiceLevelChanged event allows the client application to be notified of service level changes. This could be used for monitoring performance, or for tracking service levels against a Service Level Agreement (SLA).

The threshold value determines the circuit breaker’s resistance to failures. If a client makes a lot of calls to a service, a higher threshold will allow it more time to recover from failures before tripping. If the client makes fewer calls, but the calls are expensive to the service, a lower threshold will allow the circuit breaker to trip more easily.

Ignored Exception Types

Sometimes a service will throw an exception as part of the service logic. We might not want these exceptions to affect the circuit breaker service level. I have added an IgnoredExceptionTypes property, which holds a list of exception types for the circuit breaker to ignore. If an operation throws one of these exceptions, the exception is thrown back to the caller and is not logged as a failure.

 CircuitBreaker cb = new CircuitBreaker();
 cb.IgnoredExceptionTypes.Add(typeof(AuthorizationException));

Invoker Exceptions

If the operation invoker throws an exception that was not caused by the operation itself, then the exception is thrown back to the caller and is not logged as a failure.

Threading

As mentioned in a comment by Søren on my last post, it is likely a circuit breaker would be used in a multi-threaded environment, therefore it should be able to function property when multiple threads are executing operations.

The failure count is now updated atomically using the System.Threading.Interlocked.Increment and System.Threading.Interlocked.Decrement methods. This ensures the failure count variable is locked while being modified by a thread. Other threads wanting to update the failure count must wait until it is released.

While this does not guarantee the circuit breaker is completely thread-safe, it does prevent problems with multiple threads executing operations and tracking failures. I have to confess I’m not an expert at multi-threaded application designs, so if anyone has any further suggestions on how to make the circuit breaker more thread-safe, I would love to hear them!

For more information implementing threading, see the .NET Framework Threading Design Guidelines.

Download

Download the circuit breaker code and unit tests (VS 2008).

I hope you find these enhancements helpful. Does providing a service level make sense? How can I improve multi-threading support? If you have any comments or suggestions, please let me know your thoughts.



Follow

Get every new post delivered to your Inbox.