Pages

Sunday, 18 October 2009

A Fireside Conversation

"I had a wonderful dream last night."

"Tell me more" you say as you lean a little closer.

"Well, I dreamt that I lived in this wonderful fantasy world full of unicorns and faeries. Every day was perpetual spring and the streams ran clear and cool. I had two close neighbours and each morning one would bake bread and the other would fry bacon. Disease and crime were a thing of the past. Best of all, though, was that every public member of Microsoft's entire Base Class Library now implemented an interface."

"No way!"

"Seriously, the unicorns were beautiful."

"No, I mean the bit about the interfaces."

"Really? What, you find the rest of my utopian landscape somehow more plausible?"

"Um... yes."

"Hmm..."

"But now you mention it; that would be quite something. Imagine how easy IoC and DI would become? Unit Tests would flow from our fingers like olive oil. Simple, elegant Adapter Patterns would fill the skies like flights of swallows."

"I can almost see them."

"It can't be that difficult, can it?"

[Pause]

"Anyway, another pint?"

Tuesday, 13 October 2009

Enabling Code Coverage on TFS Build Server Without VS Test Edition

Back in May 2009 I exchanged a number of emails with Buck Hodges regarding Code Coverage on my build server. Here's my original blog: Oi Microsoft, this IS part of Development!. Basically, the upshot was if you don't have Visual Studio 2008 Test Edition installed on your build server you will not be able to run Code Coverage as part of your automated builds.

Well, I've now managed it.

To be honest I'm not exactly sure how this happened! Inside my Default.TestRunConfig file I had my main (ASP.Net MVC) project enabled. Recently, I have added more projects to my solution and their respective \bin\debug\ dlls have been automatically added to the Code Coverage list of artifacts to instrument. I then noticed that Code Coverage results were appearing in the build for these new libraries. No coverage for my main project though. The final stage was to remove the Code Coverage reference to the main project and, instead, target the resultant dll.

I now have full unit testing and code coverage on my entire solution - a result that, apparently, can't happen.

Wednesday, 7 October 2009

Dependency Inversion Pattern Clarification

Given the following 2 dependancy structures...

interface IDependancy
{
}
class DefaultDependancy : IDependancy
{
}

... I have seen many Dependency Inversion (DI) patterns implemented in the follow way...

class Worker
{
    private IDependancy _dependancy;

    Worker()
        : this (null)
    {
    }

    Worker(IDependancy dependancy)
    {
        if (dependancy == null)
            _dependancy = new DefaultDependancy();
        else
            _dependancy = dependancy;
    }
}

I'm also guessing that you've probably gotten this far, thought "seems about right" and are about to flip back to see if anything new's happened on Twitter? Well, hold on - 'cos you're wrong!

The problem with the above scenario is that it doesn't correctly convey the intention of the pattern. The content of the non-default constructor is being asked to cope with two, entirely different, situations.

  1. "Did the client intentionally, and knowingly, call the default constructor" or
  2. "Did the client call the non-default constructor directly and accidentally pass in a null reference?"

This is a perfect recipe for the most wonderful 'managed' error: NullReferenceException. This will be made even more troublesome if you haven't yet switched to using small methods as you'll have no idea what's null. Enjoy!

So, here's what you should be doing ...

class Worker
{
    private IDependancy _dependancy;

    Worker()
        : this(new DefaultDependancy())
    {
    }

    Worker(IDependancy dependancy)
    {
        if (dependancy == null)
            throw new ArgumentNullException("dependancy");

        _dependancy = dependancy;
    }
}

Now we know that if the non-default constructor's sole parameter is null then it's because there's a problem. Actively throwing our own ArgumentNullException also allows us to take control of the situation and name the offending variable.<

This simple change removes any ambiguity in your code and makes your intentions abundantly clear.

Wednesday, 30 September 2009

Can Distributed Teams be Truly Creative?

As I've mentioned before, I lead a distributed, UK-based development team. We have been using this model for a number of years now and have produced and shipped a number of quality, profitable products.

I spent all of yesterday in the same room as another developer as we blue-sky-brain-stormed-out-of-the-box (!) some solutions for an ongoing problem. What I noticed most was how easily ideas started to flow when we were both just walking around the same home office, sipping coffee, tossing a rugby ball and occasionally glancing at the same screen.

Now, we are an Agile company - and I'm not just paying lip-service to this morning's most fashionable meme. We ship regularly and often, we Scrum every morning and we hold retrospectives after every 4 week sprint. However, are we missing something? Are we missing an environment that creates those sparks of genius that turn a profitable product into a remarkable product?

Working from home has some enormous advantages:
  • No daily commute.
  • Perfect, individual working environment.
  • Flexible hours (being home for the delivery or boiler service).
  • No overtime barrier. It's easy to stop at 6pm, put the kids to bed, walk the dog and dine with your wife then carry on with work immediately after.
  • ... the list goes on.

How, then, do we combine the benefits of home-working with those of being in the same room? My understanding is that teleportation is still some way off. There is also the issue of cost. Do we rent more office space that we can sporadically utilise? That would seem like an unwarranted overhead.

I apologise if you've now read all this way, made a temporal investment in this article and are just waiting for the payback answer... cos there isn't one! Sorry.

In my defence I think my development team will be meeting more regularly and we'll see what that spawns. I will update this post as and when I discover new solutions. Alternatively, contact me with your ideas and we can start building a list of suggestions.

Saturday, 19 September 2009

Microsoft WinQual - An Oxymoron?

Microsoft has a website dedicated to helping partners develop and test quality software that targets their platforms. Unfortunately, they don't seem to have been dog-fooding their own standards.
  1. Their site is not internationalised. I live in the UK and, as such, I would like my dates to be dd/MM/yyyy and my words to have significantly less 'z's, thank you very much.
  2. It has a headline banner stating that the entire site will be offline the 2nd Tuesday of every month for 'future planning'.
  3. If you forget your password it emails your company's administrator asking them to reset it for you. Imagine my surprise when I received an email requesting that I reset the password for myself!
  4. I am currently trying to submit our test results to certify one of our products as 'Compatible with Windows 7'. Unfortunately, "The Windows Quality Online Services Web application is temporarily unavailable. Please try again later."
  5. The site only works with IE6 or higher (no support for Opera, Chrome, Safari or Firefox).
  6. Finally, they provide 64- and 32-bit versions of their self-test software. After spending quite a few hours running through the 32-bit tests (as Virtual PC doesn't support 64-bit OSs!) I was delighted to receive the following message from the website: "This site only supports 64-bit submissions."!
As a small company these acknowledgements are very important in allowing us to play with the 'big boys'. Come on Microsoft, a little help?


Follow up...

To top it all I've just tried adding the tested product to our Gold Partner status to increase our points tally - but it fails. The submission ID does not match their database records. Luckily the WinQual site has a satisfaction survey on the main page, so I thought I fill it out and submit some feedback. Yep, you've guessed it - "Page Not Found".

And finally...

Apparently the reason my partner program won't recognise the submission ID is that it takes a minimum of 15 days for the services to sync with each other. I'm sorry, this is still 2009 isn't it!?

Thursday, 17 September 2009

Why you shouldn't call Abstract Methods from your Constructor

Calling abstract methods from your constructor is bad practice as it denies your concrete class any opportunity to set itself up. This is particularly noticeable in IoC situations (e.g. Unit Testing). Here's an example...

abstract class BaseClass
{
    public BaseClass()
    {
        Setup();
    }

    public abstract void Setup();
}

class ConcreteClass : BaseClass
{
    public ConcreteClass()
    : base()
    {
    }

    public override void Setup()
    {
        // TODO: add setup code here...
    }
}

Well, that will work fine. But what if ConcreteClass is tightly coupled to another class. For instance, it could access the Configuration class...

class ConcreteClass : BaseClass
{
    public ConcreteClass()
    : base()
    {
    }

    public override void Setup()
    {
        string setting = ConfigurationManager.AppSettings["MySetting"];
    }
}

Again, no problems here. However; ideally, we would like to remove this tight coupling by implementing an IoC pattern...

class ConcreteClass : BaseClass
{
    private IConfigurationManager _configurationManager;

    public ConcreteClass()
    : this(new DefaultConfigurationManager())
    {
    }

    public ConcreteClass(IConfigurationManager configurationManager)
    : base()
    {
        _configurationManager = configurationManager;
    }

    public override void Setup()
    {
        string setting = _configurationManager.AppSettings["MySettings"];
    }
}

And this is where the problems arise. The Setup() method will now throw a NullReferenceException because the ConcreteClass's constructor has not been allow to run before its own instance methods have been called!

Unfortunately, there is nothing in the C# compiler or Code Analysis tools (to my knowledge) that will flag this as even a warning.

The solution is to recognise why you need to call the Setup method and before what other event. This normally gives you the opportunity to call it from an OnMyEvent() method.

Tuesday, 15 September 2009

RSS Mashup for VS2008

Having stared at the VS2008 homepage for more than a year now and realised that the RSS content hadn't updated, not once, I finally decided a change was in order. I use my HTC HD mobile RSSHub for all my 'real' news reading and I subscribe to over 70 feeds. VS2008 can handle one - so my options were rather limited!

That is until I discovered xFruits. They offer a blindingly simple mashup facility whereby you can take n feeds and squeeze them into one. The resultant feed itself has its own url. Now my VS homepage subscribes to one feed that contains the headlines for my most read subscriptions. The RSS -> PDF function is pretty cool too!

Simple and fantastic.