A better way to write enumerations

One thing I constantly struggle with is enumerations. They are inherently dumb, carry little more than one integer of actual information and usually mean a lot more than their name conveys.

Let aside Enumerations as method option flags (where they actually do make sense!), the usual line of business application will have these three enumerations somewhere:

image

Now, let’s ignore all the others our most basic example would be the Sex enumeration that has usually one but only one use: How to salute your user when communicating.

Like the obvious emails you get:

Hello Mr. Hölbling, we’d like to thank you for your …

You get the drift. If I’d perform a sex change someday the system should address me as Mrs. Hölbling (and actually, that type of thing is much more of a problem in German than in English, but anyway).
And the code to do that would look something like this:

string salutation = "Mr.";
if (sex == Sex.Female) salutation = "Mrs.";

Console.WriteLine("Dear {0} Hölbling", salutation);

In a typical web application you’ll be repeating this piece of code numerous times, since being polite doesn’t hurt. Where this would actually hurt is if you’d mindlessly copy&paste that piece of code wherever you have to greet your user. You’d be violating DRY and the guy maintaining your code in 2 or 3 years will find out where you live and kill you in your sleep some day.

What I’d like to see as a solution to this is to simply have a method living on that enumeration. Like:

Console.WriteLine("Dear {0} Hölbling", sex.GetSalutation());

And that’s possible, just not very convenient. You’ll have to emulate the enumeration through a class:

public class Sex
{
    public int Id { get; private set; }
    public string Salutation { get; private set; }
}

Should work like a charm, but you loose the benefit of typing Sex.Female when setting a gender. So here is how to make a class look & feel like a enum without the limitations:

public class Sex
{
    public static Sex Male = new Sex{Id = 0, Salutation = "Mr."};
    public static Sex Female = new Sex{Id = 1, Salutation = "Mrs."};

    public int Id { get; private set; }     public string Salutation { get; private set; } }

You can now do stuff like:

new User()
    {
        Name = "Daniel",
        Sex = Sex.Male
    };

And if you have added equality on the id (as you always should) you could make decisions like with real enumerations:

if (user.Sex == Sex.Female)
{
    //Do Something
}

Now you could even go ahead and subclass your Sex class and dump logic in there if you please. Hell, even persist that type to a database using NH and the WellKnownInstanceType as Fabio points out.

The full implementation of our above Sex enumeration is beyond the jump.

public class Sex
{
    public static Sex Male = new Sex {Id = 0, Salutation = "Mr."};
    public static Sex Female = new Sex {Id = 1, Salutation = "Mrs."};

    public int Id { get; private set; }     public string Salutation { get; private set; }

    #region Equality methods

    public bool Equals(Sex other)     {         if (ReferenceEquals(null, other)) return false;         if (ReferenceEquals(this, other)) return true;         return other.Id == Id;     }

    public override bool Equals(object obj)     {         if (ReferenceEquals(null, obj)) return false;         if (ReferenceEquals(this, obj)) return true;         if (obj.GetType() != typeof (Sex)) return false;         return Equals((Sex) obj);     }

    public override int GetHashCode()     {         return Id;     }

    #endregion }

Read more →

Most annoying thing to ever happen: Configuration manager screwup

I think I was pretty close to a major nervous breakdown due to this one misconfiguration of my Visual Studio that I have no explanation for:

image

Imagine yourself trying to test some new behavior that according to your unit tests works, but simply refuses to work inside your web-app because the call to it hasn’t been compiled yet!

Breakpoints don’t get hit, changes don’t appear.. Mayhem! (Oh, and to top it off, since views aren’t compile you still see some of your changes, just not the ones in real code).

I first thought it’s some problem with the ASP.NET MVC project type, but eventually I noticed that if I don’t manually recompile the project none of my changes appear.

Way to go, I should have seen that yesterday instead of spending almost an hour hunting bugs where none where to be found.

Update: To add insult to injury I again forgot that checkbox turned off after taking the above screenshot.

Read more →

Bad poor man’s IoC in default MVC template

This is directly from the standard MVC template upon starting a new project:

// This constructor is used by the MVC framework to instantiate the controller using
// the default forms authentication and membership providers.

public AccountController()     : this(null, null) { }

// This constructor is not used by the MVC framework but is instead provided for ease // of unit testing this type. See the comments at the end of this file for more // information. public AccountController(IFormsAuthentication formsAuth, IMembershipService service) {     FormsAuth = formsAuth ?? new FormsAuthenticationService();     MembershipService = service ?? new AccountMembershipService(); }

I didn’t realize this is in the default template of ANY MVC install when Ayende pointed this out in his NerdDinner review yesterday. Wow, speaking of bad defaults..

If you don’t want to burden yourself with “real” IoC, at least do it right:

// This constructor is used by the MVC framework to instantiate the controller using
// the default forms authentication and membership providers.

public AccountController()             : this(new FormsAuthenticationService(), new AccountMembershipService()) { }

// This constructor is not used by the MVC framework but is instead provided for ease // of unit testing this type. See the comments at the end of this file for more // information. public AccountController(IFormsAuthentication formsAuth, IMembershipService service) {     FormsAuth = formsAuth;     MembershipService = service; }

Read more →

MVC vs MonoRail – Action Methods

Many people have said nasty things about the Castle MonoRail framework since ASP.NET MVC has come out. Both serve the same purpose but both frameworks are pretty different. I did/do projects in both these days, and usually all features of A are also present in B, just slightly different.

One thing where this isn’t true is the layout of ActionMethods in MVC:

In short, MonoRail can have unlimited method overloads for ActionMethods while MVC can only overload twice (once for each HttpVerb).

What do I mean?

MVC:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]     public ActionResult Index(int id)     {         return View();     } }

MonoRail:

public class ContactController : SmartDispatcherController
{
    public void Index()
    {
        
    }

    public void Index(int id)     {              }

    public void Index(int id, string name)     {              } }

You can see clearly, MonoRail as a framework is much smarter about what action method it will invoke. Based on what parameters you supply it will pick the best match. 
MVC will simply use reflection to invoke any method with that name that matches the HttpVerb, so once you remove the AcceptVerbs attribute MVC will break with a AmbiguousMatchException.

MVC vs MonoRail

Just to get bias out of the way: I believe MVC is technically still inferior to MonoRail but makes that up in larger community and (much) better documentation. What you pick is largely dependant on how well you know your way around missing documentation and open source code mailing lists.

To illustrate this I went to stackoverflow and compared the number of questions tagged with asp.net-mvc with those tagged castle-monorail. The results may very well speak for themselves:

image

It’s a shame I have to say. MonoRail is such a nice framework and it really does not deserve getting stomped by ASP.NET MVC. As funny as this may sound for a OSS project, currently the best way to contribute to MonoRail is to write about it and if possible improve documentation around it. I guess that says everything about the quality/maturity of the framework.

Read more →

SSL Errors can indicate wrong system time

Imagine my face when I got the following screen while logging into Gmail in the morning:

image

Chrome really suggested that www.google.com has no valid SSL certificate and may be dangerous.
Also services like Windows Live Messenger and Windows Update refused to work due to broken SSL certificates.

Turns out, I accidentally set the system clock after a bios reset to 28. July 2008 instead of 2009. I guess I looked at the system time about 3 times before noticing the error :(.

Funny: The wrong year also prevented me from syncing the time with time.windows.com to get to the right one.

Read more →

Keeping up with Castle binaries through NAnt

One of the main annoyances of running from the castle trunk for me was copying new assemblies to my projects. Whenever I see something interesting pop up in the mailing list I usually run a SVN update to see what changed. While the castle build process is pretty simple at this point, picking the right assemblies and copying them to an ongoing project manually is just painful.

I did this exactly twice before I remembered the golden rule: automate!

This little NAnt target is now in charge of copying assemblies I need to my project’s lib directory:

<target name="castle-update">
<if test="${property::exists('castle-trunk-dir')}">
	
	<if test="${property::exists('skip-castle-compile') == false}">
		<echo message="Compiling castle trunk release binaries..." />
		<exec program="build.cmd" basedir="${castle-trunk-dir}" workingdir="${castle-trunk-dir}">
		</exec>
	</if>
	
	<echo message="copying castle binaries" />
	
	<copy todir="lib\castle">
		<fileset basedir="${castle-trunk-dir}\build\net-3.5\release\">
			<include name="Castle.ActiveRecord.???" />
			<include name="Castle.Components.Binder.???" />
			<include name="Castle.Components.Common.EmailSender.???" />
			<include name="Castle.Components.Common.TemplateEngine.???" />
			<include name="Castle.Components.Common.TemplateEngine.NVelocityTemplateEngine.???" />
			<include name="Castle.Components.DictionaryAdapter.???" />
			<include name="Castle.Components.Pagination.???" />
			<include name="Castle.Components.Validator.???" />
			<include name="Castle.Core.???" />
			<include name="Castle.DynamicProxy2.???" /> 
			<include name="Castle.MonoRail.ActiveRecordSupport.???" />
			<include name="Castle.MonoRail.Framework.???" />
			<include name="Castle.MonoRail.Framework.Views.NVelocity.???" />
			<include name="Castle.MonoRail.TestSupport.???" />
			<include name="Castle.Services.Logging.Log4netIntegration.???" />
			<include name="Iesi.Collections.???" />
			<include name="log4net.???" />
			<include name="*.license.txt" />
			<include name="NHibernate.ByteCode.Castle.???" />
			<include name="NHibernate.???" />
			<include name="NVelocity.???" />
		</fileset>
	</copy>
</if>
<if test="${property::exists('castle-trunk-dir') == false}">
	<fail message="Please specify the directory to castle-trunk through -D:castle-trunk-dir=<directory>" />
</if>
</target>

This little script will compile castle and then copy over all files I need to my /lib/castle folder, making a castle update as easy as writing:

build castle-update -D:castle-trunk-dir=..\open-source\castle-trunk

Make sure you have your /lib/ folder under source control in case some breaking changes come from the new castle binaries.

Read more →

Keeping up with Castle

Especially when trying to follow the development of a big project like Castle you can get lost quickly. There is no real “main” endpoint to refer to. Some news get out there through the development mailing list, sometimes they come through blogs and sometimes they are only present in code.

What I found useful in following the project are the following places:

  1. Castle Project aggregator – a aggregate feed of most known figures involved in the castle development process
  2. Castle Project development mailing list – The place where discussion about features and structure happens
  3. Castle Project svn log – I like to look at commits to see what’s going on
    Note: Especially with castle where the last “official” release was in 2007 it’s imo quite important to know what’s going on when you are running the trunk version.

Read more →

FileUpload in MonoRail

After a stressful week of non-computer related stuff eating up my time today I finally got around to continue some work on the imagineClub website.
I approached the section of file uploads and just wanted to quickly point out an excellent post by Ken Egozi about how to properly handle file uploads with MonoRail.

FileBinderAttribute to ease FileUpload in MonoRail – by Ken Egozi

It’s really nice to see that MonoRail has File upload baked directly into the framework. It’s as easy as that:

public void Upload([DataBind("Document")] Document document, HttpPostedFile uploadedFile)
{
	if (uploadedFile != null)
	{
		//TODO: Save File to Disk, Test this properly
	}
}

But what Ken addresses is a neat way to keep this testable without obscuring the controller code.

Also, apparently Ken has written his own weblog engine ontop of MonoRail and even opensourced it for the public to look at and hopefully learn something from it. It’s really great to see real application code somewhere instead of just samples and short demos. Also from what I saw in the repository it’s not too complex to make you cry and yet real enough to show you some interesting things about MonoRail.

Read more →

Troublesome SQL Server 2008 installation

Since Visual Studio 2008 ships with a SQL Server Express 2005 installation I never really bothered to change that. All tools I work with support that and I never needed any of the 2008 specific features before.

Only, the current imagineClub Website is hosted on a SQL Server 2008 installation, so in order to access that database on my development machine I needed to install a 2008 version.
I figured it would be best to upgrade to Microsoft SQL Server 2008 Developer edition since I can get that for free through the imagineClub MSDN AA agreement so I downloaded the ISO and started the install, expecting the setup to figure out how to upgrade my current installation.

Unfortunately that is not possible. The SQL Server 2008 setup failed miserably and the setup is not automatically rolling back. That means that I ended up with a partial 2008 install and a partial 2005 install.
Most services were installed twice and neither would work.

Unfortunately the SQL Server Setup is just a collection of MSI files that get called in some weird order through the main setup routine. Therefore the errorlog of the main install just references other logfiles that should contain error-details, but skipping through an alien 30k logfile isn’t the easiest task.

I could finally complete the setup by running the uninstall on ALL things that contained SQL in their name on my machine, until only “Microsoft Sql Server 2008 (64-bit)” was left.

image

The main SQL Server 2008 entry then told me that apparently all parts of SQL Server 2008 are gone and it will remove itself from my programs list.

I then was able to re-run the standard installation and now I’m finally up and running with SQL Server 2008!

image

Apparently I was lucky to get away so easy. If the above isn’t working you could try to follow Mark Michaelis tips on how to get rid of SQl Server 2005/2008 manually.

Anyway, uninstall SQL Server 2005 Express before attempting to install a SQL Server 2008. Saves time in the long run!

Read more →

ARFetch attribute in MonoRail

MonoRail and ASP.NET MVC while being very different both almost mirror their features. Few things are impossible in one of both and the only really major difference between those two is that MonoRail comes packed with a suggested data access strategy: ActiveRecord.

This pre-packing is completely optional, it’s very easy to implement whatever data access logic you like, but if you choose ActiveRecord you’ll benefit from some nice things like the ARFetch attribute.

See this action method and judge for yourself:

public void Detail([ARFetch("Id")] NewsPost post)
{
    PropertyBag["post"] = post;
}

You just tell MonoRail through ARFetch what request-parameter is the object’s Id and it will fetch that entity from your DB and pass it into your method. It’s so simple that it’s almost tragic, yet it’s a huge time saver in most CRUD cases (edit, update and delete usually involve fetching the entity first).

Also, for a change, ARFetch is one of those few things inside MonoRail that needs zero documentation. It just works! (Besides the fact that you need to know it exists of course).

Read more →