When to use Enum’s vs object’s

Enum’s are a touchy point with .net developers. There are the pure OO types that detest the use of them and then the perhaps more MS inclined that love the little buggers.
I will admit that I am more of the later but I have been rethinking my use of them lately and think I have settled on a few rules of thumbs that I may start to follow, which of course I would like your thoughts on.

Enum’s in the domain.
Enum’s can easily maps to reference tables in most ORM’s and so this is an easy win here. Unfortunately I am starting to lean towards the thought of not using Enum’s in the domain. The presence of Enum’s usually means different means of handling certain scenarios and instead of using ugly switch statements in the domain I am going to try to move to using objects over Enum’s, which may help with using a more robust strategy patterns.
These objects are still easily mapped using discriminators and this means it allows domain functionality in these new more DDD styled value types.
Possibly one approach is to start using Enum’s in the intial stages of mapping and as functionality grows, refactor to objects as necessary.

Enum’s over the wire
Enum’s over the wire I am completely ok with. Provided the Enum’s are well documented these little buggers just go across as the given value type you have assigned (commonly int). This keeps messages sizes down and allows the client to create an Enum on the receiving side to map to give Enum values. NServiceBus is an example of where this happens (for error codes IRC).

Enum’s in the application
I think this is where is would be most pragmatic with my approach. A lot of application developers, especially in the .Net world are more that happy to deal with Enum’s and small switch statement in the application may actually be easier for many to maintain. These may also be easier to deal with on UI displays, like drops downs as many people have standardised helpers to manipulate Enum’s. Again it really depends on the situation and how much logic is dealt with on the client/application.

Again I hope I will take a reasonably pragmatic approach to this. Hard and fast rule often mean you are unnecessarily painting yourself into a corner.

For those wondering what the hell I am talking about when using Objects as Enum’s this nasty code give a vague idea. Note that you can now subclass the type, providing type specific logic.

class Program

{

static void Main(string[] args)

{

Person bob = new Person(OccupationType.Developer, OccupationEnum.Developer);

//do other stuff…

}

public class Person

{

OccupationType occupation;

OccupationEnum occupationEnum;

public Person(OccupationType occupation, OccupationEnum occupationEnum)

{

this.occupation = occupation;

this.occupationEnum = occupationEnum;

}

}

public class OccupationType

{

public static OccupationType RockStar = new OccupationType();

public static OccupationType Developer = new OccupationType();

public static OccupationType BusDriver = new OccupationType();

public static OccupationType Maid = new OccupationType();

}

public enum OccupationEnum

{

RockStar,

Developer,

BusDriver,

Maid

}

}

Style Cop and VS Defaults

I have been playing with Microsoft new(ish) code analysis tool StyleCop over the last couple of nights (god forbid I use it on our work code base!). Its a pretty cool tool in the same vein as FXCop but with more of a focus on general code layout etc. In this regard its pretty cool. It gives you warnings for when rules are broken & it integrates into VS quite nicely. Unfortunately there is no clean way of integrating it into my NAnt scripts as there is no exe to call. Apparently you can put it into your MSBuild scripts, but that’s kinda weak that they have not provided an exe for other means… any who…

It also highlights the fact that VS default templates do not adhere to the StyleCop rules. If you run StyleCop over a standard code base you will see a bunch of warnings straight off the bat. Firstly there are no file headers on any standard C# file.

An XML type header need to be placed in every file. This to me stinks of C headers… are we not a bit past this? Is this really required? There are copyrights on the project in the assembly file, do we need the clutter on every single file (and repeated in the AssemblyInfo.cs twice)?

Well if you do then feel free to add a header similar to:

//
// Copyright (c) 2008 All Right Reserved
//
// Rhys Campbell
// rhysc@fullstack.co.uk
// 2008-09-10
//

Contains assembly information.

It also points out the VS, by default, places the using statement on the outside of the namespace which the pigs don’t like!

Fortunately there is an easy fix to these and other default behaviours: Templates.

Visual Studio has configurable templates for the files it creates, so you can modify the standard output to what you want. These template reside as zip file in the C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\ folders and are actuall cached near by in the ItemTemplatesCache folder. You can make your own personal templates and by default they hang out in C:\Users\Rhys Campbell\Documents\Visual Studio 2008\My Exported Templates\.

Say for example we wanted to trim the  StyleCop warnings of our projects down a bit then the above examples could be changed from

using System; 
using System.Collections.Generic; 
$if$ ($targetframeworkversion$ == 3.5)using System.Linq; 
$endif$using System.Text; 
namespace $rootnamespace$ 

class $safeitemrootname$ 
    { 
    } 

To something like :

//
// Copyright (c) 2008 All Right Reserved
//
// $username$
// $username$@fullstack.co.uk
// 2008-09-10
//

  

namespace $rootnamespace$ 

using System; 
public class $safeitemrootname$ 
    { 
    } 
}

To do this just crack open a new class, make the changes to the layout you want using template parameters in logical places (i.e. class, namespace, date etc) and File > Export to Template… *

You can select the namespaces required and even pick a pretty icon for your new template. This is particularly good if you use a bunch of standard classes (Tests, NHibernate, WCF all spring to mind) and it should speed things up nicely 🙂

To use you new template Just Add a new item to a project and under all the standard templates will be a “My Templates” section with your new tempate happily residing.

*If your Export to Template, like mine, is not there, go to Tools > Customise and drag the command from the depths of the hidden file options on to the file menu drop down (i.e. Commands > Categories=File > Command = Export Template..)

Build scripts

I will be honest; I am pretty much a rookie at build scripts. I know some guys out there have weird and wonderful super complex complex NAnt, MSbuild, *ake files that do everything in including there dirty washing.
Well over the last year I have usually had a build script lying around that was kinda “just there”, more for assurance that what i was doing could be easily hooked in to a CI scenario. However I have been using the build script local over VS lately and am finding it pretty good. It certainly is a lot faster just to build the soln. I can also :

  • control what gets built
  • what tests are run
  • what code analysis gets done
  • if i need a distribution zip etc

all by clicking on a different bat file.
All of my tasks are in my NAnt file and each bat file just points to a different task.
I have a quick build (no test or code analysis), a standard build (build, run all unit tests and code analysis) and a deploy (standard plus zip the required files for a deploy).
Any solution bigger than a scratch pad can really benefit form a build script. The best thing is, if you are like me and many of your solutions have the same general structure, once you are happy with your defaults then you just need to change one or two parameters in the script for your different solutions.
If you are not using a local build script i would highly recommend it. I am just disappointed I have not been using it more in the past.

Gray hairs and coronaries …

Refactoring fundamentals of a rather large stack ca be daunting… I gave it a go over the weekend, modifying hundreds of files and tens of thousands of lines of code and, to be honest, I thought I had done a pretty good job doing so.
Monday morning comes around and there where some Small build issues (csproj.user are not in the a build outside of VS) but easily fix.
The really problem was when we started to do complex interactions… the app died…

Oh sh1t…. I’m fired..

Well maybe not fired just roll back to Friday and I have wasted a weekend.
Long story short… don’t leave on Nhibernate logging… it kills your app.
Commenting out log4net returned everything to normal, now we just need to log the correct things (ie not every NHibernate interaction!)

Better Know a Framework!

In the vein of the DNR guys:

ImmutableAttribute to continuously check that a class or a structure is immutable.

PureAttribute to continuously check that a method is pure, i.e it doesn’t provoke any side effect by modifying some fields states.

default C# Keyword in Generic Code. Will return null for reference types and zero for numeric value types

These are things that i haven’t used in the past when i should have, but not any more! 🙂

Build Tools

The number of available build tools in .Net grows daily it seems… and i feel i am falling behind.
MSBuild and NAnt are the standards in the .Net world but the uprising of Ruby has formed Rake, which is also usable in .Net. Rake is a Ruby implementation of the build tool Make which has inspired the .Net equivalent Boobs Bake from Ayende and now James Kovacs has PSake (pronounced sake as in the Japanese wine)….
I really will have to look into these… jeez i still haven’t played with Power shell and my Ruby and Boo skills have a lot to be desired!

The satisfaction of refactoring

I am in the process of heavily re factoring our service facade (ie WCF) layer. the first file i got hold over i have already removed 60% of the LOC and got a significant number of the methods to one line
eg:
public GeoLocationFindByIdResponse GeoLocationFindById(GeoLocationFindByIdRequest aTransportObject)
{

return FindEntityById
<IGeoLocation>(aTransportObject.Payload,this.Domain.GeoLocationFindById);
}

that’s a big improvement from the 36 liner that it replaces and a whole lot easier to read.
One of our major issues was cut and paste code of logging and auditing/instrumentation. As we are not using AOP I have decided to go with passing delegates. It has actually sped up the method calls too as i have re factored out redundant methods calls and repeated logging. Now all of fault handling and the “aspect” like stuff can be handled in one place and the code is a whole lot easier to maintain.

Cool, i am happy with that!

Setting up a Greenfields project

My last post talked about technical investment. well like financial investment, its usually better to invest early.

Lee recently posted about Standards and Success Criteria. I think this is crucial for project success and hopefully this post is a concrete example of what I think are standards when beginning a project.

Setting up your solution well early can make life a lot easier. Some of the main concerns to me when initially setting up are as follows:

Naming
Establish a naming convention early on. It does not really matter what that convention is, just define it. There are some .Net guideline already established, use these if you don’t already have one (iDesigns coding standard is pretty good starting place).
Be sure to talk to other developers and stake holders about the names you use and change them as needed. It will much easier to change these names early one than it will later on when multiple Dev’s are in the mix and releases are already being made.
Use the correct names for commonly know things. One of the key areas I often see is pattern names used incorrectly. Make sure you understand what the pattern is if you are going to use the terms. Every self respecting developer should have GoF (or at least read it).

Libraries & tools
Define what Core and 3rd party libraries and frameworks you are going to use at the start of the project. If you are going to use .Net 3.5 and WCF use it from the beginning and use it properly.
Libries you need to consider include: Test/Mock libraries, Persistances/ORM, communication/ESB, UI, Logging, Framework (IoC, AOP etc) etc.
Tools include: Soruce control, analysis tools, code gen, IDE, CI, build, test runners/coverage, IDE plugins, documentation generators
This is also a good chance to be an early adopter. If there is a new beta release of a product you are interested in and the release is schedule for before your release, why not start using it now? Sure you will have to weigh this up yourself, however this has proved successful to me in the past.
One caveat here is make sure you know how to use the library before jumping on board. It is only after you have learnt the library that you know how steep the learning curve is. Personally I found it easier to learn a whole new language (Python) than picking up an ORM (NHibernate). Don’t drag your team through hell because you wanted to play with the latest toy.

Build process
Establish a build process early on. Set you team up for success. You may not have CI set up yet but that does not mean you cant have the solution ready to go. Have your build scripts set up before you have any significant code base. Use the build script.
Ensure the build script is doing everything is should, you should not have to move dll’s or copy config files etc. It should do it all.

Project Processes
Define how the project will be run from day one and do it properly. The term Agile is so flippantly thrown around, yet so rarely done properly… I find i quite annoying. To me its like saying I drive a Lexus when I am rollin’ in a Toyota. There is nothing wrong with a Toyota, and it may be the best vehicle for the job, just call it what it is.

Tests
Whether you are TDD or not, I assume you are writing some sort of automate-able tests, whether they are strictly unit test or otherwise. Integrate this in to your build process. As we are talking about Greenfield projects here, define your expected test coverage up front. Now this is a doable edged sword, but i think it is worth while. Also encourage your Dev to truly embrace TDD and correct UNIT testing using mocks/fakes/stubs.
On a side note, I was talking to a Java mate yesterday and apparently there is a a pug in for IntelliJ that runs your test in a back ground thread every time you build in the IDE. With the multi-processor machines we uses nowadays, why not? It got me thinking, i could pretty easily set up something like that too for my local machine.

Follow coding best practices
The first port of call in doing this is setting warnings as errors and setting the error level as high as it can go in each of your project files in the solution.
Get FXCop and use it. if there are things you don’t like then document and removed the waring, but start with it.
Some will disagree with me on this, but on this subject I say F*^K ’em. Not having these on just sets up a slippery slope. I would rather deal with the issues as they come up, not retro fix.

Follow design best practices
Terms like IoC, AOP & TDD are not just cool buzz word, they are best practices there to make YOUR life easier. Using IoC make TDD easier. Using TDD encourage the use of IoC. AOP cleans up your code from so the business problem at hand is not cluttered with technical sideshow concerns.Use these, embraces these, understand these and introduces them early on into the picture. Create a pit of success.
Also be sure to use a metrics tool like NDepend to check on your solutions health. Again, dealing with issues early may help stem some nasty heads from popping up later.

Defining future Standards and Success Criteria
This is pretty broad and somewhat recursive, but there will be personally issues that you are concerned with and project specific thing that should be address early on in the picture

Technical Investment

A recent post on Technical debt on InfoQ got me thinking about technical investment.
In the age of YAGNI, ominous PM’s and tight budgets, often time is not spent on investing technically in the team or the business. We build stuff as we need it and if we can reuse something we try to, but often end up hacking it to fit our new needs, if the shoe does not quite fit.
At my current place of work we are “post live” and in a situation where investing technically makes great business sense. Our project is some what of a flag ship project as the company is
A) New to .Net, coming from a Delphi background
B) New to NTier distributed development, coming from a rich client with db connection
C) Looking to move to an SOA architecture across the company to more cleanly delineate the business logic get some reuse out of the business processes.

Because of these factors there have been mistakes that have been made. The application we have built works but it is high in technical debt. It is just holding itself together, push it just a little and it will come crumbling down.
A lot of this is to do with hurried framework design and best practices ignorance. We have acknowledged our mistakes, but that is not enough. Over the next few months this application stack is to be used as the basis for other NTier development in the new and growing .Net department, we need to make sure the other teams don’t copy our mistakes. We need to make it easy for them to succeed!

IMO we need to start with re factoring our core libraries, specifically Data Access, Logging and Service Boundaries. These are areas that will be needed for all of the applications in the future so why not get this stuff right.
Are we using WCF as intended?
Are we getting the most out of NHibernate?
Can we reduce the noise from our non business aspects that have leaked in to our code?

Is this Gold plating? Well, yes i guess it is and i would not recommend it normally. However given the circumstance i think the cost of not getting this rights is too great.

So how would I do it if i was in the same position tomorrow as the guys were at the start of this project? Maybe that’s the next post…