Rob Smyth

Monday, 29 October 2007

Visual Studio Style Docking For Windows Applications

I'm currently using the DockPanel Suite in a little application I'm writing to give Visual Studio style panel docking. Really cool.

It is, free, open source, and easy to implement. My only critism is that the documentation is a bit fragmented. A quick starter (for C#) on the project web site would be good. Currently you need to download the separate documentation files.

So far I'm really impressed.

Using Continous Integration To Raise Code Coverage

I'm constantly amazed by what I learn working in a team, somebody is always coming up with something real useful. This last couple of weeks it was a simple extension to our continuous integration (CI) build box that measures the code coverage of the build and compares it to the highest recorded code coverage. If it is less the build fails, yep fails. If it is higher then the highest recorded is automatically updated with the builds coverage. Being a CI environment any build box failure must be fixed immediately. As a result the code coverage can only go up.

So far this has been amazing successful, but then our team does practice TDD (well mostly).

The implications are that if you are committing new code you are responsible to ensure that your code is covered by unit tests (code coverage is only calculated from unit tests). This is something of a subtle move in responsibility as before it was acceptable to 'think' that the code was covered now we must 'ensure' that it is covered or the build will break within minutes of the check-in.

For this to work developer boxes were set-up so that each developer can run their own code coverage (before check-in) and view the added code for coverage (using NCoverExplorer) quickly and easily. I think that things being easy is really essential.

Like many things I've blogged about I'm really recording great ideas from the team or others. This is no exception (credit here to Nigel Thorne ... a wickedly good idea Nigel).

Coding Standards Without Having Coding Standards

Every developer likes a coding standard, so long as it is the same as theirs. :-)

Coding standards have benefit but only if accepted by the team. When I worked at Citect they had a strict published coding standard that had been in place for many years. It worked well and every developer complied. In other companies I've worked in have either not had a coding standard, I've implemented a documented coding standard, or the standard was 'copy the standard of the file you are working in'. But in the team I'm working in I've recently realised that a coding standard has been adopted by the team over the last few months without any documented standard, meetings, or negotiations. It just evolved effortlessly and has been accepted by all. The trick was automating the coding standard via Resharper's reformat code command. Nobody, well at least everybody but the implementer, even thought of it as a coding standard!

I can not take credit for this. In fact I was oblivious to it until I realised that we had a coding standard. Being automated meant that any/all files can be formatted with just a context menu command click. So easy, that it is attractive to everybody so everybody uses it. Resharper provides both a hint and positive feedback by a small indicator next to the editor window that goes green when the file is formatted to the rules you have set. It gives markers to lines that do not comply. So easy it is attractive and the good old green positive reinforcement.

Hmm ... are developers becoming conditioned to the green colour (red-green-refactor). Kermit was wrong, it is easy to be green.

Tuesday, 16 October 2007

Web Cam Software

I'm looking for web cam software as part of our bushfire system. The idea is to enable us to view conditions at home from work. It would be great if we could view images via our phones.

I keep coming back to this so I created a wiki page to keep my notes here.

Sunday, 14 October 2007

Cheap 1000L Tank Under The House

Bought a used 1000L water tank on eBay this week for $235 delivered. $0.23 per litre is cheap and it is just a perfect size to fit under the house. The photo shows the tank being pushed under the house.

I've positioned it so that the top of the tank is level with the overflow level on the existing barrels I have collecting rainwater (you can see one in the photo). So I only have to hook them up and they all act as one tank.

These tanks feed into a small automatic pressure pump which feeds a garden tap and a sprinkler via a solenoid controlled from the home control system. I put a float switch in one barrel just below the overflow level. This is also wired to the home control system so that when the tanks are full a garden sprinkler is turned on for five minutes. The idea is that if we do not have the capacity to store the water we might as well divert it onto the garden. Hence dry spots in the garden get a higher monthly rainfall. Since Melbourne gets rain every few weeks in summer I recon this will help the garden a lot.

Sociable Golly

A few weeks back Golly became the escape artist and kept finding ways next door to play with their new puppy. They got on so well that Golly is now in demand next door so the two puppies can play for hours. We took him in at about 8am this morning and picked him up at about 1pm. Apparently they just ran, rolled, and generally played for all that time!

Proud of him. He is a gentle but confident dog. Sue ought to take a lot of the credit. She insisted he go to puppy school and has also taken him to a nearby training school. The socialization is good, we can see the difference.

Wednesday, 3 October 2007

Sue want a Mini Cooper

Sue brought a demo Mini Cooper home today. I took it for a drive up and down the mountain. While it is not a car from me (I do not like it) I can see why Sue loves it. It has an amazing safe feeling on the Mount Dandenong Tourist Road, it takes the bends with amazing confidence. Mind you, I've not a new car for some years but it does feel like it is stuck to the road.

What I did not like was the delayed power when using auto but when you do take the plung to manual it is much better. Thing is manual in the mini is kinda auot-manual as there is no cluch, the gear changes are via steering wheel pads, and the engine does take a fairly wide rev range. Manual mode is easier than it sounds. I also found it a bit noisy and rough, but then it seems to be designed for a more 'sporty' feel. Sue loves it.

So I can see the attraction ... but not for me thanks.

Friday, 14 September 2007

Virtual Build Box Lava Lamps

Continuous Integration is the blood supply of an XP style team. The visibility of build box failures and time broken is important. It helps the team focus on keeping the build pristine. The team I'm working with uses CruiseControl to fire a warning audio and to change the state of a tray icon. This is great, particularly the audio, but it does not give us indication of how long it has been broken. So come back from lunch and not notice, or we loose the plot for a few hours and forget it.

One solution is to use Lava lamps. As they need to warm up their activity gives a nice feedback of just how green or how read we are. But they need power wiring (You could use the CruiseCotnrol X10 interface) and control and how do you handle multiple builds and multiple boxes?

The other option is to dedicate a screen on a wall. One company I worked with displayed the state of all builds on all boxes as a grid on this screen. It could be seen across the floor and worked well. But it does require a dedicated box and screen etc .

So what about the new digital picture frames now on the market. One from ThinkGeek looks interesting as it can be updated my email so a build box only needs to send an email. This means that a more informative and dynamic display in a team pit without the overhead of computer. I like the idea.

My thoughts of an ideal virtual lava lamp set-up:
  • Audio play on build failure and on build fixed (as provided by CruiseControl tray tool).
  • Screen in team pit displaying status as colour and animating time broken.
  • Tray icon access for build box details (e.g. CruiseControl tray tool).
  • Screen displays a history graph one or two (only) metrics like build time, code coverage, or number of unit tests. Whatever the team feels helps them at that time.
Perhaps I can use it at home to tell me if I have email, the weather forecast etc.

Wednesday, 5 September 2007

Dependency Injection - Ninject

To evaluate Ninject I downloaded the binaries and created a VS project to play with. First question was how to use it. I could not see any doco in the downloads (I only downloaded the binaries) and the web site gave a nice intro but no setup info I could immediately see (I'm impatient). So I tried adding a reference to Ninject.Core.dll. This worked well with the simple web guide.

My test was to implement a dog owner (John Smith) with two dogs. John is a singleton and he names his dogs. Each dog has tail and a mouth that can bite. Pull the tail and he bites! This is designed to test a singleton object with multiple instances of another object. Those objects (the dogs) do in turn have other objects with circular references (dog has tail and tail is attached to dog).

This was easy except that Ninject was unable to resolve a circular dependency (using a constructor and method injection combination). I had hoped that the instances would be created and then the method injection done.

Note: Comment from Nate (see comments below) points out that Ninject does resolve circular dependencies. Looks like my test was wrong, I will retry it again in the next couple of days.

Here is the code:

class Program
{
static void Main(string[] args)
{
IKernel kernel = new StandardKernel(new RunTimeIoCModule());

IJohnSmith johnSmith = (IJohnSmith)kernel.Get();
johnSmith.PatDog("Rover");
johnSmith.PatDog("Rex");

johnSmith.ChangeDogsName("Rover", "Spike");

IJohnSmith johnSmithAgain = kernel.Get();
johnSmithAgain.PatDog("Rover");
johnSmithAgain.PatDog("Rex");

johnSmithAgain.PullTail("Rex");

System.Threading.Thread.Sleep(3000); // just time to see the output
}
}

public class RunTimeIoCModule : StandardModule
{
public override void Load()
{
Bind().To();
Bind().To();
Bind().To();
Bind().To();
}
}

[Transient]
public class Dog : IDog
{
private ITail tail;
private IMouth mouth;
private string name;

[Inject]
public Dog(ITail tail, IMouth mouth)
{
this.tail = tail;
this.tail.SetDog(this);

this.mouth = mouth;
}

public string Name
{
get { return name; }
set { name = value; }
}

public void Pat()
{
Console.WriteLine("Dog '{0}': Pat - thank you", name);
tail.Wag();
}

public void Ouch()
{
Console.WriteLine("Dog '{0}': Ouch!", name);
mouth.Bite();
}

public void PullTail()
{
Console.WriteLine("Dog '{0}': Pulling tail - watch out!", name);
tail.Pull();
}
}

[Transient]
public class Mouth : IMouth
{
public void Bite()
{
Console.WriteLine("Bite!");
}
}

[Transient]
public class Tail : ITail
{
private IDog dog;

public void Wag()
{
Console.WriteLine("Tail Wag");
}

public void Pull()
{
Console.WriteLine("Tail Pull");
dog.Ouch();
}

public void SetDog(IDog dog)
{
this.dog = dog;
}
}

[Singleton]
public class JohnSmith : IJohnSmith
{
private IDog dog1;
private IDog dog2;

[Inject]
public JohnSmith(IDog rover, IDog rex)
{
Console.WriteLine("Hi, my name is John Smith.");

this.dog1 = rover;
this.dog1.Name = "Rover";

this.dog2 = rex;
this.dog2.Name = "Rex";
}

public void ChangeDogsName(string oldName, string newName)
{
IDog dog = GetDog(oldName);

if (dog != null)
{
dog.Name = newName;
}
}

public void PatDog(string name)
{
IDog dog = GetDog(name);

if (dog != null)
{
dog.Pat();
}
}

public void PullTail(string name)
{
IDog dog = GetDog(name);

if (dog != null)
{
dog.PullTail();
}
}

private IDog GetDog(string name)
{
IDog dog;

if (dog1.Name == name)
{
dog = dog1;
}
else if (dog2.Name == name)
{
dog = dog2;
}
else
{
dog = null;
Console.WriteLine("I do not have a dog called '{0}'.", name);
}

return dog;
}
}

I've not published the interfaces to save space. I used interfaces to support TDD.

Tuesday, 4 September 2007

.Net Dependency Injection Frameworks - Part 2

Searching for a Dependency Injection Framework (IoC) my first pass has narrowed the contenders down to:
For my criteria and a list of other frameworks see the 'Part 1' post.

NinjectStructureMapMicroKernelPuzzle.NetImportance
License
Apache 2 OSS

essential
C#55

4
Doco34X
X4
XML config04

2
Programmatic config54

10
Constructor injection4Y

20
Method injection4?

4
Private field injection4?

3
Setter injection4
4

3
Singleton activation44

10
Transient activation44

10
Other activation45

3
Simple to use4?

20
Multiple configs45

5
Contextual binding45

4
Generic types3
4

2
NMock injection34

4
Maturity
5

4
SCORE
58
57
XX

Note: Above chart updated following Nate's comment (see comments below).

I eliminated MicroKernel as I could not find focused documentation (not related products) and what I could find turned out to be links to Porn site adverts. I gave up on Puzzle.Net as I could not find any documentation web pages.

So I'm down to Ninject & StructureMap and wondering if I ought to take a closer look at Spring.Net as it mentioned often on the web.

I will continue to update this another night. Looks like the next step is to try some sample code.