Posts Tagged ‘Test Driven Development’
Tuesday, June 23rd, 2009



Just read a post by Sahil Malik where he gives his reasons for saying

TDD + SharePoint 2007? Well - screw it! Not worth it IMO.

The reason for his statement is that he sees the actual C# code developed as being a very small % of the total SharePoint project and the effort to do this as not worth the return when you consider the project costs overall.

The problem is, like so many people, he is getting TDD mixed up with doing good development.  He dismisses TDD because it is harder to do in SharePoint because of the API.  It’s not TDD that makes it harder,  it being able to isolate the API and design testable code that is harder.

If you listened to the SharePoint Podshow I did with Eric Shupps we were in agreement that what actually mattered was that you developed good quality code,  that you had the processes in place to enable code reviews, unit testing, integration testing, and the like, that all go together to ensure the code you do develop for your SharePoint solutions is Enterprise ready.

I hold my hands up, I do talks on TDD and SharePoint.  I don’t do this because I think that everyone should do this on day one,  I do it because people have used SharePoint as an excuse to not doing quality development.  The comment ‘we can’t do unit testing because we are using SharePoint’ has been common among development teams,  other just don’t do unit testing anyway so it never even cropped up.   So if I can demonstrate the you can go all the way and actually code your solution using a technique like TDD then this argument no longer holds water.

What the question should be

Quality Development and SharePoint, is it worth doing?

And the answer to that is a big Hell Yes!

And if your happen to use TDD to write some of that quality code, then that’s good too.

The key thing to remember is that you need to make a judgement call about the value; in Sahil’s defence he did mention this.  What I can’t take is that he adopts the ’screw it’ stance before he even starts. This to me is a much of a problem as the people at the other end of the spectrum that think you can ONLY code using TDD.

Friday, May 15th, 2009



If your the only member of the team is it really worth going through the same agile development process that you would in a team of eight?

Isn’t it quicker to just crack open Visual Studio and start coding?   After all your the customer so you know what you want right?   You not going to have to deal with any of the social complexities that conspire against you. You’re going have the hottest of communication with the dev team,  the dev and test roles will have an interment knowledge and the scrum master won’t really have to do anything as there is not going to be any blockers on this project.

Right?

So I started down this path and before I knew it I had some weird project created with bits of code and SharePoint artefacts but not really seeming to make any progress.   I was easily distracted by other things and didn’t really have a feel for how long it would take and when I could say I was done.

STOP!

What was I doing!  I spend my time trying to help people develop better, to take small steps and sometimes big steps to help produce better software..   why was I not practicing what I preached?

I stopped!

Deep breath, deleted all the rubbish I can previously created and got back to basics.

The Team

I have a team,  the fact that some (in this case all) of the roles were done by the same person was ok; that happens often in agile teams.

Design

Yes, you heard me right here.  Eric Shupps would be proud of me :).   I’m not going to jump into Visual Studio and crank out code starting [TestFixture] I need to do some design work first, even though this application is going to be small I still need to put in the time on the upfront design.  I need to think through the solution at a high level.

Here I used the opportunity to try out the great Balsamiq application,  which I stumped up the $79 license fee for and download the desktop version.

Blurred out Balsamiq Design

I’ve deliberately blurred the image but you get the idea of what the mock ups look like, and these take only a matter of minutes to produce.  Definately something you should consider if your currently trying to do this in Visio or heaven forbid cranking out HTML mockups.

The few UI based mockups actually helped me to understand how the application would work for the end user, which in turn provided a clear vision for the way the solution would be developed.

User Stories

I didn’t need to do any remote collaboration on the User Stories so I was able to get back to basics and use one of the white boards in my office as the task board.   I wrote the user stories out on post-it notes and added them to the board along with rough estimates for each one.

image

Here you can see I’m using a very common step of status on my task board

Backlog - This is where I add all stories that came out of the design,  they are all user focused with nothing specific about the implementation.  No stories like ‘Use jQuery to make it nice’  these are user stories.  If I think of something while i’m coding or testing, or even having a beer I can just write it to a post-it and stick it on the backlog.

Sprint - I like Scrum so adopt a Scrum Esq. style to my process.  The sprint will be where I put the stories I plan to do next.  The amount is based on the estimate and also the sprint length.   In this project I’m doing stupily short sprints of 2 days each.

In Progress - When I pick off a story to work on it goes in here,  if you’ve ever looked at the Kanban approaches your looking to keep this ‘In Progress’ to a defined level.  I like to try and move things through to ‘Done’ before picking off new stories.

Verify - When I think it’s been coded properly and dev tested I move the story here.   Verify is where I would validate the code on another environment - i.e. a non-dev box,  one with multiple web front ends.  At this point I also look at introducing some form of automation for both the build/deployment and also the acceptance testing.

Done - This is when it is really really done,  there is nothing left to do, no documentation, no tests or tweaks,  the code is production ready.

Sprint 1 - Day 1

Having selected the user stories for the sprint it was time to setup my dev project and get some of the foundations in place.   If you follow me on twitter you will know that I previously spent time producing a decent SharePoint development Virtual Machine so it was very quick for me to roll out the few things I needed to get going.   A SharePoint team site in which I could spike and test my code,  a VS2008 solution and class library project in which to start cranking out some code.

At the end of Day 1 my board looked like this:

image

One of the stories I felt was ready for verification and another I was making good progress on.   At this point I had nothing ‘Done’ my burndown in the morning would look a bit sad,  but that’s OK that is often the case at the start of a project or sprint.  I also don’t at this point have a verification setup so this is going to slow me down a bit on Day 2.

Day 1 has been good,  I have the basic project structure defined.   I was able to build a WSP with the SharePoint features I needed to complete the first story and was able to deploy and test this on my dev machine.

People that have read my blog or seen me talk at conferences and user groups know that I am very keen on doing things right; I like to see Unit Tests and better still I want to see people at least trying Test Driven Development.   However at the end of Day 1 I was yet to write a single line of C# code, neither in test form or production code.   So did I really do development on day one?

Well I think I did, only the language used was XML and a little bit of CAML and for these items I do not know of any way, that makes sense, to unit test.  I often think that the XML we define as part of SharePoint projects are more inline with doing configuration,  we are just setting up SharePoint using a specific configuration and the testing for this should naturally falls into the integration space and will be picked up during verification.   That is not to say as a developer I do not validate it,  I need to ensure that it works as expected in my environment before I can move it over to the Verify column and it’ is the job of the tester to make sure this happens.  For this project the tester (me) was adamant that it all worked as they didn’t want to have to waste time on silly errors.

Interesting Test

One thing that I will be having to do with this project is fit it around real work, the sort that helps to keep food on the table sort of work.   This means that the sprints although 2 days in length the elapsed time may be significantly longer.  I know that this will impact on the velocity as I will lose some of the momentum during these breaks, however the benefit I have from adopting a more defined process is that it will be significantly easier for me to pick up the project.   Imaging if I had to go back to the mess of code I had originally created after a weeks break!

I’m really interested to see if my agile development with a team of one really does make a significant impact on the way I develop the code, on the time it takes to complete it and on the quality of the solution created at the end.

Find out what happens on Day 2.

Sunday, March 15th, 2009



How many times have you added an additional parameter or bit of logic to your code because you thought it could be useful and it’s easier to add whilst your already changing the code?   If you are your introducing Future Creep!  and should stop doing it.

What does Future Creep mean?

If your from from an XP (Extreme Programming) background you would know this better as YAGNIYou Aren’t Gonna Need It!   I actually prefer the term Future Creep I first saw on the post, beware of future creep by Jamis of 37 signal.   Everyone understands the terms Scope Creep and Feature Creep and its easy to spot these, although often ignored.  Future creep is the adding of additional code by the developer because they can see a possible future requirements.

DONT DO IT!

You may think, hey it’s only gonna take me a couple of minutes to add this additional parameter which I can see being really useful in the future.  You add the code and then move on,  from that point forward that additional code needs to be maintained, every time a developer interacts with your code they need to read it and understand it - often taking more time as that bit of the code is never actually used, which leads to uncertainty about the code.

It happened to me

The reason I wrote this blog post was an example of future creep on a recent project that had a measurable impact on time and effort. The future creep was was simple, the developer was writing a light weight logging library and decided as part of the Logging.Log() method that if the code had a HTTPContext they would also initialise the current web using SPContext.Current.   None of the code within the internal methods made use of this it was just setup and passed into the method.  This in itself does not sound to bad and for most scenarios the code did run with a valid SPContext h0wever this future creep caused a number of issues which forced developers trying work around it

  1. The logging library could not be used in code that had elevated privileges as SPContext.Current throws an error if accessed under a different security context
  2. The logging library could not be used where a HTTPContext existed but no SPContext, as was the case for some of the Exchange integration code

Having battled with solutions to the second scenario and getting comments about not wanting to make changes to the Logging Library because the dev was not comfortable with the way it had been implemented I challenged the original author of the code as to the requirement for SPContext.

The answer:  Future Creep

A few minutes later the extra code was refactored out, and the library could be used.

Lessons Learnt and how to prevent it?

Don’t do it,  resist the temptation, remember:

The best way to implement code quickly is to implement less of it.

The best way to have fewer bugs is to implement less code.

And adopting techniques like Test Driven Development force you down a path that doesn’t allow it.

Tuesday, March 10th, 2009



SharePointPopShowLogoEver wondered if it was possible to do Test Driven Development on SharePoint projects?   Have you been reading the blog posts and white papers here at 21apps.  Got involved in the debate with Eric Shupps?

The SharePoint Pod Show team finally tracked me, Andrew Woodward, down for a series of in depth interviews late one night during the MVP Summit 2009.   The Pod Show is broken into 3 parts with Rob Foster asking about the basics of Test Driven Development and SharePoint;  Eric Shupps, the SharePoint Cowboy, asks about the value TDD provides to the Enterprise and finally Spencer Harbar asks the challenging questions about how TDD helps reduce the risks to the enterprise by adopting TDD.

Hopefully you will agree that some of the myths around TDD have been dispelled by these insightful SharePoint Pod Shows.   I encourage you all to sign up for the European Best Practices SharePoint Conference in London, 4th to 6th April 2009, where we hope to continue the discussion around this challenging topic.

Don’t forget to sign up to the legendary SharePint once again organised by the Andrew Connell.

Finally, in the words of Spencer Harbar (sorry Eric no pictures of Spence!)

image

Thursday, March 5th, 2009



A short and to the point post by Dror Helper at Typemock looks at industry findings on the cost benefits of doing TDD.

The Cost of Test Driven Development

..the research proved two points:

  1. Using TDD reduce the amount of bugs in the code significantly
  2. Using TDD takes more time then not using TDD

This is in line with what was expected, the question is does the extra time doing TDD reduce the quality or is it the unit testing.  Could doing Test Last unit testing give similar results?

There is also the unquantifiable part to the numbers in the quality of the developers in each team.  This has a significant impact on the code quality.  Using processes like TDD help to raise the bar for all of the developers and the cost benefit will improve over time.  It would be a very interesting exercise to see how these numbers work out in a typical SharePoint project.

On the same lines Phil Haack (great name) has a post on Bug Driven Development where he quotes Robert Glass and Steve McConnell on the costs not doing some form of automated testing which reinforces the value in getting the right processes in place.

Tuesday, February 10th, 2009



In contrast to the Agile SharePoint development with Scrum session this was very light on the slides.  In good Agile tradition I adopted a Pair Programming approach with me at the keyboard and the audience been my code buddy.  Everyone was provided with a copy of Uncle Bobs Three rules of TDD to help with during the pairing process.  The rules state:

  1. You are not allowed to write any production code unless it is to make a failing unit test pass.
  2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

I did have some slides to set the scene (see below), to give some background to TDD and raise the issues around the use of the word TEST.  We also looked at 10 reasons TDD sucks, with a slight SharePoint slant,  and quickly got into Visual Studio where the real learning was to happen.

The user story was to develop a Magic 8 Ball web part that could have custom answers defined in a SharePoint list.  The finished code is available on CodePlex and it is planned to extend this solution over time to expand on the ideas.  My main issue with just getting the finished code is the learning is in the process and it can be hard to see how the design was driven by the code.   I am planning to do a web cast on this to show this process.

CodePlex project now available  http://www.codeplex.com/sp8ball

Winners

The guys at Typemock we very generous in donating 3 copies of Isolator for SharePoint which is an essential component for anyone doing unit testing in a SharePoint environment.  The lucky winners were

Mark Freeman
Shahar Tamari
Kennedy Duncan

Each of you will receive a free license for Isolator for SharePoint,  for those that did not win Typemock are running a special discount.

Tuesday, January 27th, 2009



This post is part of a series on Test Driven Development - Using Dependency Injection

In this 5 part series we refactored the solution developed in our white paper Unit Testing SharePoint - Getting into the Object Model to make the code more testable, and enable us to work within the available features of TypeMock Isolator for SharePoint.

We started with a review of the code and the specific line of test code that was not supported,  reviewed the options available to us including upgrading to the Full version of TypeMock but decided to refactor the code and introduce a pattern called Dependency Injection.

Before digging into the code we introduced some of the common TDD vocabulary including Loosely Coupled, Dependency Inversion, Dependency Injection and Inversion of Control.   The aim not being to scare people off with fancy terms but to help understand what these mean and the affect they have on your code.

The refactoring of the code began in Step 1. where we started to implement Dependency Inversion to give more control to our calling code, in this case our tests.  We introduced abstract classes and the use of an Interface to support this.

Step 2 Implemented dependency into the GetRandomMessage method and also the concept of creating Fake classes that can be passed in to support the tests we wish to perform.  At the end of this step we were able to refactor our initial failing test and all the tests passed.

The code for this refactor can be downloaded from here.

This blog series proved a valid exercise in refactoring existing code to make it more testable and also demonstrated that the reduced features of Isolator for SharePoint, at a reduced price point, do allow you to do TDD in SharePoint.

Whats next?

Andrew Woodward, follow him on twitter, will be speaking at the Best Practices SharePoint Conference in San Diego on in Feb 2009 looking at agile SharePoint development with Scrum and Test Driven SharePoint Development.

Monday, January 19th, 2009



This post is part of a series on Test Driven Development - Using Dependency Injection

We introduced some terms previously to help describe some of the things we need to do in order to make our code more testable and started the refactoring of our solution in Step 1. In this step we are going to complete the refactor and implement Dependency Injection in the RandomMessage class.

There are a couple of ways to pass in the object we want to work with; we will use the Constructor as this is probably the most common and easiest to use.  We have a few things that we need to do to complete the refactoring

1. Updated the tests to pass a RandomNumber object into the constructor of GetMessage

2. Update the GetMessage class to support the passing in of the RandomNumber object

3. Create a fake of the RandomNumber class that implements the IRandomNumber interface so that we can test our code

4. Confirm we have fixed our test and all tests pass.

Because we previously refactored out test code to have a setup method we only have to make one change to use the planned constructor.

[SetUp]
public void SetUp()
{
      message = new ObjectModel.RandomMessage(new RandomNumber());
}

We then update our production code to support this new Constructor, it should look like this with the constructor highlighted.  The GetRandomMessage method has also been updated to use the _randomNumber variable.

    public class RandomMessage
    {
        IRandomNumber _randomNumber;
        public RandomMessage(IRandomNumber randomNumber)
        {
            _randomNumber = randomNumber;
        }
        public string GetRandomMessage(string WebUrl)
        {
            string message = "";
            try
            {
                using (SPSite site = new SPSite(WebUrl))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        SPList messages = web.Lists["Messages"];
                        int rndMessage = _randomNumber.GetRandomNumber(messages.ItemCount);
                        message = messages.Items[rndMessage].Title;
                    }
                }
            }
            catch (UriFormatException)
            {
                message = "Error: Please provide a site url for the message list.";
            }
            catch (ArgumentException)
            {
                message = "Error: Messages list could not be found";
            }
            catch (FileNotFoundException)
            {
                message = "Error: Site could not be found";
            }
            return message;
        }
    }

To get the solution to compile you can update the WebPart class with the similar change to the one in the tests.

Running the tests you should see your previous tests continue to work, showing once more the value of the tests - we refactor with confidence, we know that when done our production code still does what the developer wanted it to do.. it continues to meet the specification.

Meets the specification,  what am I taking about!  Doesn’t the code pass the tests?

I’ll leave this question with you for now,  I will be talking about this a lot over the coming months..

Back to our Red bar which should look something like this

image

The observant among you will have noticed that the error has changed.  We are no longer getting a warning from Isolator about unsupported objects.  What we now have is a genuinely failing test.   There is a chance that your test may have passed, its a slim chance, as our test was asserting that we returned the 100th message from the list.  If your call to the GetRandomNumber returned 99 it will match.

Obviously this is not acceptable, and is the reason we introduced Dependency Injection.   Rather than faking the return from GetRandomNumber using Isolator (mocking) we are going to pass in our object that implements the same IRandomNumber interface.  If you remember back to when we Introduced some terminology we talked about loose coupling.   Our GetRandomMessage class is now loosely coupled to the RandomNumber class so we can create our own, based on a common Interface, and use this instead.

We create our own test class that allows us to define the values returned from the GetRandomNumber method.  You could put this in it’s own .cs file depending on how you like to structure your projects - personally I keep this in the same file as the tests that use it.

Continuing the principle of only coding what we need to our new fake class should look something like this

    public class FakeRandomNumber : ObjectModel.IRandomNumber
    {
        #region IRandomNumber Members
        public int GetRandomNumber(int max)
        {
            return 99;
        }
        #endregion
    }

We have hard coded the return value of 99 as this is what we want to fake - to return the last item in the list.  If we added more tests that need different values we may extend this with a simple property that allows us to set the return value within the test.

Update the test to use the FakeRandomNumber we just created, we will need to define our own instance of the RandomMessage class.

//Act
ObjectModel.RandomMessage message = new ObjectModel.RandomMessage(new FakeRandomNumber());
string rndMessage = message.GetRandomMessage("http://validsiteurl");

We have our green bar,  and everything passes.

image

In the final part of the series we will review the changes we have made and how TDD really does help you design better code.

TDD SharePoint - Using Dependency Injection Summary

Tuesday, January 13th, 2009



This post is part of a series on Test Driven Development - Using Dependency Injection

We introduced some terms previously to help describe some of the things we need to do in order to make our code more testable.  In this step we are going to start the refactor to  support Dependency Injection in the RandomMessage class.

The code that is causing us a problem when using Isolator for SharePoint is in the GetRandomMessage method.

        public string GetRandomMessage(string WebUrl)
        {
            string message = "";
            try
            {
                using (SPSite site = new SPSite(WebUrl))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        SPList messages = web.Lists["Messages"];
                        int rndMessage = GetRandomNumber(messages.ItemCount);
                        message = messages.Items[rndMessage].Title;
                    }
                }
            }
//*... snipped for brevity ...*//
        }
    }

What we need to do is use Dependency Inversion, that is we want to allow our calling code to decide what is used to get the random number.  To achieve this we need to create an interface for a class that we will allow us set define the way get our random number.

Visual Studio was really designed with agile developers in mind.   In order to achieve our refactoring we can do the following.

Highlight the method GetRandomNumber, right click on the code and choose Refactor.  Should see something similar to the image below

image

Choose the Extract Interface option which will provide you with a dialog to define the new interface name (IRandomNumber), the .cs file and also the methods that will be extracted.

image

Click OK and Visual Studio will do some of the work for us.  It does not however do everything so we will continue to fix up the code.

1. In the newly created IRandomNumber.cs files make the interface Public

As we are doing TDD we need to review our tests as the ones for the GetRandonNumber method will now be against a new object.  You may want to split out the tests into another class or .cs file but for now we will just refactor the tests that will change.

The tests should look something like below,  the code won’t at this point compile as we don’t yet have this class.

        [Test]
        public void GetRandomNumber_PostiveRange_ReturnValueInRange()
        {
            ObjectModel.RandomNumber randomNumber = new ObjectModel.RandomNumber();
            int messageId = randomNumber.GetRandomNumber(1);
            Assert.AreEqual(0,messageId);
        }
        [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void GetRandomNumber_Zero_ThrowException()
        {
            ObjectModel.RandomNumber randomNumber = new ObjectModel.RandomNumber();
            int messageId = randomNumber.GetRandomNumber(0);
        }
        [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void GetRandomNumber_Negative_ThrowException()
        {
            ObjectModel.RandomNumber randomNumber = new ObjectModel.RandomNumber();
            int messageId = randomNumber.GetRandomNumber(-1);
        }
        [Test]
        public void GetRandomNumber_MaxValue_ReturnValueInRange()
        {
            ObjectModel.RandomNumber randomNumber = new ObjectModel.RandomNumber();
            int messageId = randomNumber.GetRandomNumber(int.MaxValue);
            Assert.GreaterOrEqual(messageId, 0);
            Assert.LessOrEqual(messageId, int.MaxValue);
        }

Add a new class to the UnitTest.ObjectModel project called RandomNumber.  Make this class public and implement the interface IRandomNumber.  Next we need to remove the code from the RandomMessage class.   This involves removing the implementation of the IRandomNumber interface that Visual Studio added and also moving the GetRandomNumber code into our new class which should look similar to the code below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnitTest.ObjectModel
{
    public class RandomNumber : IRandomNumber
    {
        public int GetRandomNumber(int max)
        {
            if (max < 1)
                throw new ArgumentOutOfRangeException(
                    "max", max, "Maximum value must be greater than or equal to 1");
            Random rnd = new Random();
            return rnd.Next(max);
        }
    }
}

At the moment our code will be in a state of flux,  it still won’t compile as the GetRandomMessage method needs to be updated,  we will add a new instance of the RandomNumber class and call this method on this.  We’re not doing the dependency injection just yet.

Once this change is implemented we should be able to compile the UnitTest.ObjectModel project.   To compile the tests we need to comment out the call we make to mock out this method (this was the method that caused us issues testing with Isolator for SharePoint).

In the method GetRandomMessage_MultipleMessages_ReturnMessage comment out the line

//Isolate.WhenCalled(() => message.GetRandomNumber(1000)).WillReturn(99);

Our solution should now compile and running the tests all except the one above should pass.

A quick recap shows that we have refactored our solution, extracting the RandonNumber method into it’s own class based on an interface and run all the tests to show the code works as expected.   This is one of the big values of doing TDD,  we can make some major refactors in our code and know when we’re complete because the tests pass.

In the next next step we are going to use the IRandomNumber interface to implement Dependency Injection.

Step 2. Implementing dependency injection into GetRandomMessage

Friday, January 9th, 2009



This post is part of a series on Test Driven Development - Using Dependency Injection

There are a number of terms that you are likely to hear very early on in your journey to Test Driven Development, these terms generally refer to specific patterns of coding that have developed to support particular problems.  You should be familiar with terms like Singleton and Factory which are used as a common vocabulary and help developers to communicate their design.

In order to complete the refactoring of our project we will introduce some new terms Loosely Coupled, Dependency Inversion, Dependency Injection and Inversion of Control to help us describe the changes and the reasoning behind them.

Loosely Coupled

Coupling refers the relationship between two modules. In a loosely coupled relationship the modules relate to each other through a common interface and are not concerned with the other modules internal implementation. Changes to one module does not require a change in the implementation of the other; one of the benefits of this loose coupling is that it makes testing easier, it allows us to replace the real modules with fake ones during testing. The fake modules will implement the same common interface allowing the module under test to work without any changes.

In order to be able to achieve this loose coupling we need to implement the Dependency Inversion principle.

Dependency Inversion

The Dependency Inversion principle is used to ensure your code is loosely coupled and therefore more testable. Often people will not mention this instead they will refer to Inversion of Control or Dependency Injection, described below, however when dealing with Unit Testing Dependency Inversion is really at the heart of what we are doing.

In simple terms dependency inversion means we flip things so that the calling code is the one that decides which implementation will be used, hence ‘inversion’.

In order to achieve this we use Dependency Injection.

Dependency Injection

This really is a grand term for what is a very simple concept a way of providing an object with the variables it needs.

Dependency Inversion = give the calling code control over which variables are used

Dependency Injection = a way to pass those variables into the object

An example here will probably help, the code sample shows how the Sample object (class) defines and instantiates the RandomNumber object (class)

public class Sample
{
    private RandonNumber _randomNumber;
    public Sample()
    {
        _randomNumber = new RandomNumber();
    }
    public string GetRandomMessage()
    {
        ...
        int messageId = _randomNumber.GetRandomNumber(itemCount);
        ...
    }
}

This example is tightly coupled as the Sample object explicitly creates the RandomNumber object that is then uses internally, the code below demonstrates how we have refactored this to use the Dependency Injection pattern and enable loose coupling.

public class Sample
{
    private RandonNumber _randomNumber;
    public Sample()
    {
        _randomNumber = new RandomNumber();
    }
    public Sample(RandomNumber randomNumber)
    {
        _randomNumber = randomNumber;
    }
    public string GetRandomMessage()
    {
        ...
        int messageId = _randomNumber.GetRandomNumber(itemCount);
        ...
    }
}

Passing an object into the constructor means we now have Dependency Injection as we can pass the RandomNumber object in; and Dependency Inversion as our calling code controls which type of object is used.

A surprisingly simple concept and implementation that tends to be over complicated. There are a few other ways of achieving the dependency injection through setters and interfaces  but these are just variation on the same concept.

If you now think about this for a moment and consider the common layers you have in your application this could be Data Access Layer (DAL), Business layer, UI and possibly others like payment services and authentication, this dependency inversion at each layer would mean that ultimately all of your dependent objects need to be defined at the highest level the UI which is not really a good idea. To address this we have the Inversion of Control pattern.

Inversion of Control

When Inversion of Control is discussed today it can be used in place of Dependency Injection or more likely as a reference to the frameworks that help to manage the dependencies of loosely coupled systems. These may also be called Inversion of Control Containers.

We are not going to look at Inversion of Control as part of this series, however it is useful to be aware of the terminology.

In the next part of our series we are going to look at implementing the changes in our project, starting with the abstracting of a common interface.

Step 1. Refactoring

Further Reading

The concepts above are not new and there is a lot of further information available, these are some of the articles we found useful in putting together this simple overview.

Coupling (computer science) - WikiPedia

Dependency Inversion - WikiPedia

Dependency Injection - WikiPedia

Dependency Injection Demystified - James Shore (Must read!)

Inversion of Control and Dependency Injection: Working with Windsor Container - MSDN

Inversion of Control Containers and the Dependency Injection Patter - Martin Fowler (reading this last)