Rob Smyth

Thursday, 28 May 2009

Storing a .Net C# Generic Type Parameter

From time to time I hit the problem where I have a call to a generic method where I need to resuse the generic type for later use. Today I think I found a simple pattern that solves the problem.

A code fragement explains all (I hope):
  public class MyRegister
{
private List<IToken> tokens = new List<IToken>();

public void HasService<T>()
{
tokens.Add(new MyToken<T>());
}

public object[] UseRegisteredGenericTypes()
{
List<object> results = new List<object>();

foreach (var token in tokens)
{
results.Add(token.DoSomethingWithMyType());
}

return results.ToArray();
}
}

public class MyToken<T> : IToken
{
public object DoSomethingWithMyType()
{
// Do the stuff here like ... return myApp.DoStuff<T>();
}
}

Sunday, 26 April 2009

Seduced to Compliance by the Process's Dark Side

Bloged on PL's suggestion ...

Working in a Agile fashion can be hard. It means collaboration, passive compliance is not enough. Using eXtreme Programing processes is even harder. XP is a set of high discipline processes. But I've often noticed that the jargon of both Agile principles and XP processes are just too easy to misinterpreted. This has lead to the birth of an Agile and XP dark side, an interpretation that absolves developers of all responsibility, encourages passive compliance, and gives the customer god like powers. It moves responsibilities to the customer.

The XP Dark Side seems to me like planning for failure in a way that the developers cannot be blamed. It is the customer who will be left holding the baby. Real seductive if you want to code without responsibility.

The most recent XP Dark Side smell I have come across is the:
'A story is what the customer says it is.'
All hail the customer :-)

The customer is seen as an all powerful, all knowing, boss figure. The developer a passive compliant servant. Sometimes this comes from the customer as:
'I'm the customer, I can do anything I want.'
Command and control? Certainly not agile.

A collaborative team (which includes the customer) should never move forward without the customer's full agreement, so at the end of the day the story will always be what the customer, and the team, say it is. The customer is a vital leader and owner here, but he/she is not all knowing. The team has a responsibility to work with the customer. Collaboration (Agile) is a choice, but if taken, it requires everybody to contribute to help.

I think that an Agile developer's responsibility includes investigating the cause of defects to validate the design and remove the source of future defects. Code health is the team's responsibility. To delegate this to the customer leaves a conflict of responsibility which results in the 'oh that happened because you did not let us ...'. To delay the investigation distorts velocity and the work must be done and leaving it only increases the cost.

So customers ... beware of the dark side :-)

Friday, 17 April 2009

NCover Scalability

We seem to have hit a glass ceiling with NCover on our build process. We run NCover on all builds to ensure that coverage does not fall (thanks to NCoverCop). In the last couple of days we have started to get out of memory exceptions. It seems that the process of generating a coverage report just takes too much memory.

The project is significant but not large (yet) so this was a surprise. The solution seems to be to break up the coverage test into multiple build tasks.

Thursday, 16 April 2009

Is Domain Entity Migration The Real Need?

'Data Migration' has always been a real 'challenge' in each project I've been involved in. Sometimes it is a seen as migrating application file format, other times database schema. I wonder if the perception does not match the need and hence ends up more complicated than necessary.

Where the file / database is used to persist an application's state or configuration, and not raw data to be processed, I'm thinking that they are presenters (aka UI forms) that happen to provide persistence. This perspective moves the focus to being able to migrate application objects, the file format is an 'end to means' rather than the objective.

The 'need' is to be able to restore an application's state. Maintaining some presentation of the that sate (ala file format) is one of multiple solutions and not the objective/need. These conversations so often come down to what we think is possible rather than what is needed.

I'm hoping to use this approach with NXMLSerialiser (to be known as NSerializer) so that migration can be supported independent of file format such as binary or XML. It is the objects that matter.

A snapshot of my current thinking:


public class VersionMigrationBuilder : IVersionMigrationBuilder
{
public void Build(IVersionMigrators migrators)
{
migrators.PriorToVersion(1, 2, 3).UseMigrator(new V010203Migrator());
migrators.PriorToVersion(1, 2, 2).UseMigrator(new V010202Migrator());
migrators.PriorToVersion(1, 2, 1).UseMigrator(new V010201Migrator());
migrators.PriorToVersion(1, 2, 0).NotSupported();
}
}

public class V010201Migrator : IMigrator
{
public void Build(IVersionMigrator versionMigrator)
{
versionMigrator.ForType("TypeNameA")
.RenameTo("TypeNameA_new")
.DiscardField("noLongerLovedField")
.RenameField("oldFieldName").To("newFieldName")
.SetNewField("newFieldName").To(42);
}
}


I'm keeping notes here.

Tuesday, 14 April 2009

Iffy Density - A Useful Metric?

Any mention of code metrics is on slipery ground. Metrics are good, given a problem, and are best only used until the problem is solved...


I wonder if an 'Iffy Density' (my invention until I'm told otheriwse) is a useful metric to indicate code health and probable defect density.

Iffy Density is a measure of the number of 'if' / 'case' statements within a method or class. Will these add to code's TLA infestion with MID and CID :-)?

Monday, 13 April 2009

Using Subversion Revision as the AssemblyVersion - Revisited

I've been using MSBuild tasks for a while to automate the generation of an AssemblyInfo.cs file with an AssemblyVersion that matches the current Subversion revision (commit number). See my prior post here. But, I've had mixed success with that approach and this posting is about using the Tortoise SubWCRev.exe utility that I hope will be more appropriate to open source projects.

The Need
  • Automate the file and assembly version numbers to use the Subversion revision number for the revion number in '...'.
  • Make the project configuration visible in the Visual Studio 2008 UI.
  • Suitable for debugging by typical developers using the VS2008 UI.
  • Project compilation without third party application installation.

The Problem

The MSBuild community task approach works but its configuration is obfuscated from the typical software developer user. It requires all users to have the MSBuild community tasks installed on the developer's (user) PC. That alone is not the 'obfuscation', thing is that if a user tries to build the project on a PC that does not have the MSBuild communicaty tasks intalled they are given an error that cannot be fixed withing the Visual Studio 2005/2008 UI that they are using. This is the critical 'usability' issue that I have found.

It has not been such a problem for commercial use as a software devs are resolved early and only once on each developer box and probably documented for future developement or maintenance.

But I have found it to be a big inhibitor for open source software users. The code cannot just be download and compiled without either reading all the documentation to find such details (a deoderant ... it ought to be self evident or, better still ... just work). It means that if you have many users you will incur a significant support cost or the inhitor will reduce user product acceptance. In other words ... ungood.

The Solution

After much googling I came across Bruce Boughton's blog showing how to use the TortoiseSVN SubWCRev.exe utility in a pre-build event. His solution did require a little pocking around in the Visual Studio project file and also required TortoiseSVN to be installed on the PC. I've adapted it a bit here is my solution:

  1. Add the existing AssemblyInfo.cs file to Subversion's ignore list. This file will be replaced by the auto generated file later.
  2. Copy your existing AssemblyInfo.cs file to a file named AssemblyInfo_temp.cs. This will become the source file used by the auto generator. Move this new file into the Properties folder by drag and drop in VS Solution Explorer pane.
  3. In the new AssemblyInfo_temp.cs file add required SubWCRev.exe keywords. We want to set the version revision so change your [assembly : AssemblyVersion("1.0.0.0")] to [assembly : AssemblyVersion("1.0.0.$WCREV$")]. If you want the FileVersion to be the same, delete the FileVersion entry.
  4. Copy the TortoiseSVN SubWCRev.exe file into your source tree. I keep a Lib folder in the root (trunk) of all my project source folders. In this case I copy the file to Lib\TortoiseSVN\SubWCRev.exe to make it clear it is a TortoiseSVN file. This way anybody can download the project and compile without the need to install TortoiseSVN (although anybody using Subversion should anyway).
  5. Now add as a project pre-build event: $(SolutionDir)..\Lib\TortoiseSVN\subwcrev.exe $(ProjectDir). $(ProjectDir)Properties\AssemblyInfo.cs.tmpl $(ProjectDir)Properties\AssemblyInfo.cs.
Done. This solution does require copying a TortoiseSVN file into your source tree. TortoiseSVN is an open source project, check its license to be sure you can use it. Otherwise install TortoiseSVN and reference the installed file.

Friday, 13 February 2009

A Support Antipattern

Yea, a negative post about a company. I wondered if to mention the company, but in the online community we have a responsibility and, I recon, these guys have raised the bar in how to not treat a customer.

Last week I placed and order with I-Tech and to their credit they delivered what I ordered fast. But on receiving the order I realised I made a mistake. I ordered the wrong item. Yep, no doubt, my mistake. I can use the one I ordered but another would be 'better' (I can live with that).

So, I was wondering if I could exchange it for the one I wanted. I emailed the company making it clear that it was my error. I would have only been 'disappointed' if they said a 'sorry ... but no' but the treatment I got was ... well ... 'disappointing'.

Here is a good lesson on what not to do ....

I sent my first email to 'sales', my first surprise was their response:
Please write the email to our RA department. Their email address is RA@i-tech.com.au
doh!

Okay, so sales does not talk to 'RA'. So I forwarded the email to 'RA' (twice). They did not respond. Hmmm, not a good impression so far. I went back to sales@i-tech.com to tell him/her/them that I had not got a response ... now I getting a real bad impression of this company and then I get the response:
Was the item opened?
I told them in my original email, but okay ... pressures of business. Some poor bugger sitting at a desk. So, I respond that I had not opened the box. The email form 'RA':
If the box had been opened, we wont be able to accept your return.
What! Why tell me that? Why try to aggravate your customer for no reason? Okay, now customer relationship is not the best but then I get another email from 'RA':
Sorry, I just spoke with my supervisor, according to our company policy, we can not exchange an item simply because the customer ordered the wrong item or changed their mind
"simply because the customer ordered the wrong item" ... true, and no doubt this is what the supervisor said, but gosh, not the best customer communications. (thx for the 'Sorry' though).

You gotta wonder about the management of this company. They did deliver what was ordered well. But, if there is a problem with the order?

Good script for the next 'The Office' TV series?

Tuesday, 27 January 2009

To Revert Is Right To 'Go-on' Is To Look Good

As people come onto a team using continuous integration (CI) we usually hear:
  • 'I cannot commit as there are too many changes. (Has not committed changes as done)'

  • 'I cannot commit as I have conflicts. (Has not updated frequently)'
It is a learning curve, and usally works out. But now a new guys gave some great feedback (in my words as I do remember the exact quote):
The thing I have taken on is that reverting my changes enables me to deliver faster.
So true. But I notice that when somebody says at stand-up that they did X hours and then reverted all changes, it is often seen as a failure. An intereting reflection on time to deliver working code to measured effort/behaviour/complexity/expired time/working. I think we have another dimension to software development about measuring success.

Words seem to lead us. 'Perfromance' is about an act, delivery of working functionality in minimal time is about efficiency. Would we be better off talking about efficency than perfromance?

Monday, 12 January 2009

Compliance/Collaboration Confusion

I've realised that collaboration can be confused with compliance, and when it is, collaboration can then be confused with resistance.

Thursday, 1 January 2009

Does Microsoft Not Want Australian Money?

I've been using a trial version of Visual Studio 2008 for a while now and the time has come to buy a license. So I click on the VS2008 license pop-up which takes me to Microsoft's site ... a couple of hours later I've given up. I do not think it is possible for somebody in Australia to buy a license on-line from Microsoft.

The Microsoft site takes you to their "Windows Marketplace" which is a front end to a regional "Microsoft Store". You must select a country ... no surprise Australia is not listed. Only about half a dozen countries are listed and I tried all of them. If you choose USofA you need to enter a US state. If you choose UK then your offered European countries, but no Australia. Similar story for the others, or I could not read Japanese, Korean, German, etc.
I tried navigating from the AU site and tried different links. Humbug! I'm feeling very unwanted. I dunno if it is a web site fault, an oversight in letting us know we a 'special', or if I've just missed the right link.