Category Archives: Interfaces

Pluggable Dependencies demo part 1

I’ve been itching to build a “modern” application using an Agile approach with TDD since being inspired by Rob Conery’s MVC Storefront application, so  I figured the small example I discussed in my last post would be a good starting point for me to take my first baby steps.

To briefly re-cap and pad out the initial requirement, the idea is to build a small app where a person (and their address details) can be stored. There will be a minimum requirement that a person must have a full name (forename and surname) and an address for that person to be “published” to a list of people on the system. Draft person records can be created with incomplete details, and stored until such a time when they can be completed and published.

Please keep in mind as you read this that this will be this first time I’ve *attempted to* use TDD in anger, so please feel free to confront me about any questionable decisions I make, and I’ll try and make time to adjust the app/discuss the issues further!

Right, without further ado I’ll begin!

The first unit test

In attempting to follow the TDD mantra, the first step is to code out my first test. I figure I’d start with trying to return a list of people (or Persons) and since I know from my last post I want program against an abstraction, I know this list will be of type IPerson. Since I also know I wish to filter this list, I want my return type to be IQueryable. So this leaves me with:

public void Repository_ShouldReturn_Persons_AsQueryable()
    IDataContext rep = new InMemoryRepository();
    var query = from persons in rep.Repository<IPerson>()
                select persons;

    Assert.IsInstanceOfType(query, typeof(IQueryable<IPerson>));
    Assert.IsTrue(query.Count() > 0);

Of course since the none of these objects exist yet, the code will not build. With a little help from Resharper it’s easy to create some empty interfaces for IDataContext and IPerson and a basic implementation of InMemoryRepository to enable this code to build. These interfaces and classes now sit in the test project, within the InMemoryRepositoryTests code file and are marked as internal. At this point, this doesn’t matter. There’ll be a time to sort this out later in the process.

Now at this point, I run my first test, and of course, it fails – my repository method throws a NotImplementedException. At this point I really want to cheat a little since I already have an implementation I can use for this method that I’d like to use, but I know I would probably be burnt at the stake for such a blatant abuse of TDD, so I grit my teeth and continue. The TDD process tells me I should be adding the simplest implementation possible to make the test pass, so I write:

public IQueryable<T> Repository<T>()
    IList<T> items = new List<T>();

    return items.AsQueryable();

…and it fails again. This time with the message "Assert.IsTrue failed." – of course, there is no data being returned. Duh! This is easy to fix, I know I need to return a list of IQueryable<Person> so I add the following lines just above the return statement:

IPerson person = new Person();

This time, I run my test, and watch it pass!

Now I’m allowed to refactor. This is once again where Resharper comes in really handy; a few Alt+Enters and I’ve separated my objects and interfaces into separate files. I can then move IPerson and Person into a separate project called business objects (for want of a better name) and move IDataContext and InMemoryRepository into their own project (aptly named DataAccess). A few more tweaks are needed (like changing the protection level of the classes from internal to public, and altering namespaces) and I hit my next point requiring consideration – since I am making reference to the person object in the InMemoryRepository class, there is a one-way project dependency from my DataAccess project, to my BusinessObjects project and it appears that the dependency is avoidable. Since I want to avoid this dependency, I refactor the implementation to allow items to be inserted to an internally maintained list of objects:

private readonly List<object> _inMemoryDataStore = new List<object>();

public IQueryable<T> Repository<T>()
    var query = from objects in _inMemoryDataStore 
                where typeof(T).IsAssignableFrom(objects.GetType()) 
                select objects; 
    return query.Select(o => (T)o).AsQueryable();

public void Insert<T>(T item)

I then add the Insert definition to my IDataContext so I can initialise the test with some data. Now my code builds again, I can now run my test again watch it pass!

Phew! That’s all I’m going to cover in this post. In later posts I will try to cover off returning Address details related to a person, implementing repositories that persist data to a database, implementing a “draft” repository, and switching between the pluggable dependencies.

Program against an abstraction, not an implementation

I was asked by another developer today how I would go about enabling an application to record “temporary” incomplete data for a particular object (lets say, a person) where usually that object would require particular attributes to contain values, and perhaps pass some other validation (lets say, the person must have address details). Now my first thought was that I’d require different objects for the temporary person record, and the final, published person record, and that each could have different levels of validation applied. At this point, my mind wandered to a blog post I’d read somewhere before…

In the end, I answered his question by pointing him to the blog that I had read. This blog discusses the Repository Pattern and goes on to propose a super-flexible repository interface that allows different implementations of the repository to be swapped out – the primary goal being the ability to run unit tests in isolation (without hitting the database). The blog also emphasises that the power of an abstraction is it’s transparent plugability; the ability to swap in a “draft repository” is now made possible and changes made in draft can be persisted to a different storage location than the live data.

It’s not a big leap from here to see how different implementations of an IPerson interface could have differing validation logic depending on the context (draft or published). By programming against the abstraction of the repository interface, and against abstractions of the returned types, we can (with minimal effort) swap out different implementations to provide the required functionality. I’d quite like to have a go at implementing this technique myself to see what I can come up with. Perhaps in future posts I’ll explore this technique further.