Friday, December 11, 2009

Setting up and using KDiff in Visual Studio

One of the things that really sucks when using TFS is the integrated Diff and Merge tool which it ships with. I’ve tried out a few merge tools, and the one I was using previously was pretty good (I didn’t think a merge tool could get any better), and if you decide you don’t like KDiff then I would recommend giving it a try.

http://www.sourcegear.com/diffmerge/

Anyhow, a work mate recommended KDiff, initially I didn’t like the look of it. The user interface isn’t very inviting, if anything its rather intimidating. However once you get past its initial complexity its actually very simple and easy to use. Not to mention its quite powerful, and its three way merge algorithm is even more clever than TFS (its not hard tbh).

First download and install KDiff: http://kdiff3.sourceforge.net/

Next let’s set up visual studio to use it instead of the built in one, for both diffing and merging.

Go to tools and options.

image

Then select Source Control in the left pane, followed by the Visual Studio Foundation Server child item.

image

Hit the configure User Tools button.

image

Hit the Add button, and setup your comparison tool with the following data:

Extension: .*
Operation: Compare
Command: <location>\kdiff3.exe
Arguments: %1 --fname %6 %2 --fname %7

Next setup your merging tool with the following data:

Extension: .*
Operation: Merge
Command: <location>\kdiff3.exe
Arguments: %3 --fname %8 %2 --fname %7 %1 --fname %6 -o %4

Nice, you’ve setup KDiff as your default tool! The next post will outline some useful shortcuts and features.

Wednesday, December 9, 2009

Finding the root of all evil

Recently I was trying to fix a bug on a project I’m currently on, however in trying to fix it I found another 2-3 issues which I deemed more critical so I was slightly side tracked.

After fixing the other problems I returned to the bug I initially wanted to fix, only to find its already been fixed, great! Well it should have been.

The bug in question is when clicking a button on one of our wpf screens. A NullReferenceException was being thrown when attempting to load a dialog. The mischievous piece of code was this:

var startData = new ProductCodesDialog.StartData(hierarchicalCodeType)
{
DefaultSearch = productCodes.Trim().FinderSplit()
};

The problem? productCodes which is a string was null. This is fine and there’s probably nothing wrong with binding to null string values. But this piece of code was relying on the string being empty instead.

So the fix that I found nicely patched into place was the following:

if(string.IsNullOrEmpty(productCodes))
{
productCodes = string.Empty;
}

If something’s Null and we don’t want it to be null, then we just initialise it right? There was another piece of code in the actual textbox control which had something to say about that...

/*
* This fix below is for a strange issue whereby deleting all
* text in the textbox is not updating the source.
*/
if(Text != null && Text.Trim().Length == 0)
Text = null;

So this value is being constantly set to different values because dependant code is scared of throwing exceptions. Let’s take a look at what the value is initialised to so we have a starting point.

private String _value = String.Empty;

So whoever created the base type StringWithMatchType designed it with String.Empty being the starting value, IMO we should probably respect that as a heap of functionality has been built on top of this.

So why is it being set to null in the control? Apparently the bound object is not getting updated when someone selects all the text and deletes it. So let’s see if it’s the case... *a few minutes happened here* and to cut a long story short it does appear to be the case. So the new question becomes:

Why doesn’t my binding update to string.Empty when the textbox text is deleted? After a bit of Googling I found this:

http://jeffhandley.com/archive/2008/07/09/binding-to-nullable-values-in-xaml.aspx

So WPF is being carful not to null a bound property, not the ideal behaviour in this case. Ideally we want a string.Empty but perhaps WPF can’t be sure of what to do. Never-the-less luckily we are using .NET 3.5 SP1, and with that comes a handy binding property by the name of TargetNullValue

http://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.targetnullvalue.aspx

So while this issue doesn’t affect the code above, as it’s binding to a string and does correctly propagate a string.Empty, it does affect some other places we are using the same custom textbox control. Wherever we are binding to Nullable<T> values seems to be affected, whether WPF doesn’t update the bound object when the textbox is emptied. I can only assume it was for this case the Text property on the custom control was being nulled. Using the TargetNullValue we are able to get around this:

WPFControls:TextBoxWatermark Text="{Binding Path=Value,TargetNullValue={x:Static System:String.Empty},UpdateSourceTrigger=PropertyChanged}"

And when retesting this the Nullable property is correctly being set to null when the textbox is emptied.

A dash of curiosity coupled with an inquisitive nature and a distaste for quick hacks seems to have got this problem resolved in quite a satisfactory manner!

Tuesday, December 8, 2009

Regex.IsMatch always returning true?

The following code was failing:

[TestMethod]
public void ShouldNotMatchInvalidCharacters()
{
Regex regex = null;
string invalidString = null;
bool result = false;

Story.WithScenario("matching invalid characters")
.Given("a regex expression",
() => regex = new Regex(@"[0-9]*\.{0,1}[0-9]*"))
.And("an invalid string",
()=> invalidString = "a")
.When("we check whether we have a match",
() => result = regex.IsMatch(invalidString))
.Then("the match should fail",
() => Assert.IsFalse(result));
}

It turns out it was matching on the empty string. I couldn’t think why on earth it was doing this. A bit of googling and the correct way to match on an entire string is to specify the start and end of the string in the regex.

^[0-9]*\.{0,1}[0-9]*$

The test now goes green!

Monday, December 7, 2009

PDC Downloader FileNotFoundException – Update 6

Big thanks to Sam for diagnosing and suggesting how to fix this one. It turns out System.Threading (Parallel Tasks Library) was not being copied in as a referenced assembly, I thought it was.

Anyhow – in the usual fashion, there's a new version:

download

Friday, December 4, 2009

Getting things right the first time round

After releasing the PDC downloader application I have learned quite a few things the hard way. Releasing any software, be it open source, free or with a limited target audience comes with the same strings attached as any software.

For this tool I wanted the code base to be nice, feature set to be just enough, to be well tested and to learn a few things on the way. In this way it turned out to be a great success, but in trying to keep things lightweight and push versions out early I made some critical errors.

  1. Do not underestimate the usefulness of automatic updates. No matter how small the application, you always want to keep your user base up to date. Even if the updates are tiny and incremental, reaching everyone that has already downloaded a previous version is vital. There will come a time when something show stopping happens, and its a pain for your users to have to manually get an up to date version. In this respect, I really wish I employed the use of something like ClickOnce from the start!
  2. When I hacked the UI together, I wanted it to be functional so I didn’t mind having a basic UI. But to be honest the UI was too basic, which actually made it less functional than I intended. A few hours in blend would have easily rectified this which is another thing I wish I did from the start.
  3. And finally error reporting. It’s fine to set up a log file so all exceptions are logged somewhere. But this isn’t much use to users who just want to download something and have it work. Something simple like making it easier for users to email an exception is something which should have been there from the very beginning.

I really hope I won’t make these mistakes in the future.

Putting it together series – Part 2: IoC Container (Castle.Windsor and Fluent Castle)

Introduction

Whenever I need to put even a simple application together there’s always a whole bunch of infrastructure I need to put in place. For a WPF application this can include:

  • IoC Container
  • Testing Framework
  • MVP / MVVM Framework
  • Logging
  • ORM

This was recently the case when putting together the PDC downloader.  So I’m going to put a quick post around each of these areas. Besides the UI Framework everything else should convert over to ASP.NET without too much difficulty.

There is going no be no real example as I don’t want to complicate the solutions. Each solution will contain the minimum code to get the relevant area up and running, with the smallest example I can give. Once you have things going, Google will provide more advanced help.

Part 2: IoC Container

So we have our testing framework in place, the next step is to put in our IoC Container so we can dependency inject domain services in our business objects, or UI services into our UI objects. If you want to know more about what IoC and DI is there is a host of information explaining the technology and how to use it. This guide will be around setting up one of my preferred containers and integrating it with the tests we already have.

The container in question is Castle.Windsor which IMO is one of the more powerful and configurable containers available. It has good performance and is easily extensible offering some powerful extension points. It is also one of the more popular containers offering great documentation (both on the official site and by 3rd party bloggers), as well as lots of adaptors to plug it into various other frameworks.

So let’s get started, we really want to use the latest code and the easiest place to get it is here:

http://hornget.net/

Clicking on IoC gives us access to the latest build of the Castle.Windsor trunk, exactly what we need! We’ll need to set up the following referenced assemblies in our solution:

image

Now we already have an entity from the last example called SillyPoco, and a service which its dependent on called ISillyService. So what we want to do is create a concrete SillyServiceImpl and inject that into our SillyPoco object.

We’ll start with a test:

[TestMethod]
public void ShouldInjectSillyServiceIntoMyObject()
{
SillyPoco sillyPOCO = null;
bool result = false;

Story.WithScenario("a plain old nbehave spec")
.Given("an object we are going to test",
() => sillyPOCO = FrameworkHelper.New<SillyPoco>())
.When("we call a method on the object",
() => result = sillyPOCO.TalkToService())
.Then("the service should have been called",
() => Assert.IsTrue(result));
}

So we’ve made the service contract return a boolean, and we are checking that it should return true. We’ve also got a static helped method called FrameworkHelper.New<T> which will create our object that needs to have dependencies injected. Here’s how it looks:

public static T New<T>()
{
return Container.Resolve<T>();
}

That looks good, this is how we will ask the container for instances of our dependency injected objects. This is a simple implementation of the ServiceLocator, for something more advanced I would recommend: CommonServiceLocator which Castle.Windsor is compatible with.

So we have a method to get our objects, let’s setup the container. Since we are in a test project we should probably refactor the setup into a test base class to be shared throughout the tests.

protected override void Establish_context()
{
base.Establish_context();

WindsorContainer windsorContainer = new WindsorContainer();
windsorContainer.Register(
Component.For<ISillyService>().ImplementedBy<SillyService>(),
Component.For<SillyPoco>().ImplementedBy<SillyPoco>());

FrameworkHelper.Initialize(windsorContainer);
}

We've now set up our container. Essentially what we’ve told it is:

  • If anyone asks you for a ISillyService, return a new instance of SillyService
  • If anyone asks you for a SillyPoco, return a new SillyPoco and insert a new instance of ISillyService into it.

So now when we run our test it goes green! Now we have our container set up, it will start getting much easier to put our application together!

You can find the code for the examples at the bitbucket repo:

http://bitbucket.org/naeem.khedarun/projectpit/overview/

The samples for this part are under a tag called parttwo. Simply get the repository and update to that tag.

Wednesday, December 2, 2009

PDC Downloader – Major Bug Fix

Unfortunately the PDC Sessions file the application was using had some corrupted session codes, which meant these sessions could not actually be downloaded. A work mate of mine (Robin Prosch) luckily brought it to my attention (Thanks!).

image

In order to side step this, the application goes to http://micrsoftpdc.com/videos to get the available sessions and the downloads should now work correctly. I highly recommend getting this update if you want to download any of the affected sessions (there are quite a few!).

The application start up time has taken a couple of seconds hit but its well worth it for getting an up to date list of sessions (and correct!), although I don’t think its likely to change at this point.

Sincere apologies for this one, I wish I’d spotted it sooner!

download