Videos on CQRS


This is more a future reference to me, but here’s a couple of excellent videos on Command Query Responsibility Segregation.

  1. Command Query Responsibility Segregation– Udi Dahan
  2. CQRS and Event Sourcing – the Business Perspective– Greg Young
  3. CQRS: Why, What and How– Ian Cooper
  4. CQRS Pattern, Event Sourcing and Their Real World Applications– Neil Robbins

author: Luke Smith | posted @ Friday, July 02, 2010 3:47 PM | Feedback (0)

When is an email address not an email address?


When it’s a string.

How many systems have you worked on where you pass strings/integers etc about for email addresses and passwords among other things.

Edit: I knew there was a real term for this, which Rob has reminded me - Business Primitives

What’s wrong with this?

You’re adding a lot more work to any methods that deal with email addresses. If your methods accept a string, even if the parameter name is “emailAddress”, what is stopping me from passing a value that doesn’t represent a valid address. The answer nothing. This puts the responsibility of validating the input on the called method, likely raising an exception if it doesn’t agree with what you’ve passed it.

Extension methods get used, and abused, for checking whether a string is a valid email address. The fact you are doing this with an extension method should indicate that a string is probably the wrong type.

So what can we do instead?

I believe a better approach is to represent the value with its own type. Create an EmailAddress type and have this do the validating and parsing of the actual value and have methods accept parameters of this type. No longer will you have conditions spread throughout your codebase and no more will you have to trace to find out how and where the incorrect value entered the system. You get instant feedback as soon as you try treating an invalid value as an email address, stopping it moving deeper into the system.

Passwords *should* be encrypted so generally you store the encrypted value as well as a Salt. value. Why treat these two values separate (a string for the encrypted value and a string for the salt), bring them together under a Password type. You then have a logical place to create passwords from plain text and compare whether a plain text string is the same as an encrypted password.

But what about my ORM?

Any decent ORM, such as NHibernate, will allow you to map a custom type. NHibernate enables this via the IUserType interface.

Show me the code

I have posted both my implementations for the EmailAddress and Password types over on github. I’ve also added gists for the associated NHibernate user types.

Another thing to think about is to not use integers to represent Age. Age generally cannot be negative, unless you have some complex domain, so using a type which allows this may not be the right solution if you are putting conditional checks throughout the system.

author: Luke Smith | posted @ Tuesday, June 15, 2010 1:19 PM | Feedback (0)

The When, What and Why of auditing


One of the things I’ve come across in most systems is the requirement for auditing.

As i see it there are 3 approaches to auditing

  1. When - Keeping track of when something changed. e.g Product A was changed by Bob on 1st April 2009.
  2. What - Keeping track of what changed - e.g Product A's price was changed from £15 to £20 by bob on 1st April 2009
  3. Why - Keeping track of why something changed - e.g Product A's price changed from £15 to £20 by bob on 1st April 2009 because it was wrongly priced originally.

Number 3, why, provides the most value. Not only does it allow the users of the system to be able to see the intent of changes (providing an extra dimension to reports) but it also provides some valuable information to any developer tasked with fixing an issue in the system. If a developer can see what the users intent was then it can help in providing a possible diagnoses.

As a more detailed example imagine you own an online shop that allows users to be able to cancel orders before they are actually shipped from the warehouse. You could provide a big button that says "cancel order". Simple, but this would not give a reason behind the user cancelling their order.

A better option would be to give the customer a set of options as to why they want to cancel, is it because they’ve since found it cheaper elsewhere, decided they don’t want it anymore, have heard "the next big thing" is due out in a week and are waiting for that or that it is taking too long to dispatch? Capturing this information allows audit reports to be run in the future about why customers are cancelling their orders.

Once you know the intent behind the customer cancelling the order you can then initiate different business processes, if it is because they've found it cheaper elsewhere then this could invoke a process for the sales team to contact them to match the offer. If its because its taking too long to dispatch then send them a voucher for free delivery on their next order. Keeping the customer happy is more likely to make them return.

Without catching the intent (whether for auditing or not) this would not be possible.

author: Luke Smith | posted @ Thursday, February 04, 2010 11:43 PM | Feedback (0)

Write today, wrong tomorrow


My blogs been without a subtitle for as long as I can remember, I just couldn’t think of anything “catchy”. But now I have come up with something that I think fits “Write today. Wrong tomorrow”.

This refers to the constant learning that occurs in the development world. I’m a huge believer that if you look back at code written 6 months ago and think “wow, that was amazing – I wouldn’t do anything differently” then you haven’t learnt anything new since.

So take whatever I say on this blog with a pinch of salt, I might not necessarily agree with it in 6 months time – that includes the subtitle ;)

author: Luke Smith | posted @ Monday, January 18, 2010 4:47 PM | Feedback (0)

Creating website installer using WiX


I’m currently working on a new project and one of the things I want is an easy deployment process. Rather than wait till I actually want to deploy the site to production to put something in place I’ve decided to build it early and use the same process as part of my CI process. Testing the process early and often will mean any issues will be solved sooner rather than on the day of the release.

I decided to go with an msi installer, so had 2 choices. Either using a Setup Project, that’s included in Visual Studio, or WiX. WiX is far more powerful, and also doesn’t require Visual Studio being installed on the build machine (Setup Projects aren’t supported by MSBuild and so you have to use devenv.exe to build them…urgh).

WiX is a Windows Installer toolset and you write your installation packages using XML. It’s a Microsoft project and hosted on sourceforge.

The following uses wix3.0.5419 and requires Visual Studio 2008.

Step 1: Download WiX

Download WiX from sourceforge. Make sure you also install Votive (included in the WiX installer) which will give you support for creating WiX projects inside Visual Studio with full intellisense.

Step 2: Create a new WiX project

Simple, just as you would any other Visual Studio project.

image 

Step 3: Adding the WixIIsExtension

WiX provides a template to work with when creating a new project, which is useful. The first thing we need to do is reference to WiXIIsExtension, which provides us with the tasks needed to create websites and virtual directories from the installer. References are added in the same way as any other project reference, via the Solution Explorer.

image

You then need to add a new xml namespace to the Wix root element in your Product.wxs file. If you don’t do this then I’ve found you cannot make use of the tasks provided by the extension library and will get the error “The Component element contains an unexpected child element 'WebSite'.”

Add the namespace xmlns:iis=”http://schemas.microsoft.com/wix/IIsExtension”.

image 

Step 4: Creating the website

In the Product.wxs file you can now add a task to create a website in IIS within a Component.

image

Update the ComponentRef under the Feature Id=”ProductFeature” to point to the Website component, Ctrl+Shift+B and you’ve created an installer that creates a website under IIS.

Step 5: Run the installer and view the result

Find the installer that is produced in the bin directory and run it. There is no UI for the user to interact with, and a new website is created pointing to C:\Project Files (x86)\WixSampleProject

 

 

 

 

 

image

We’ve not included any files in our installer, for that I use heat which I’ll blog about in a future post.

 

Hope you’ve found this helpful

 

Technorati Tags: ,,,

author: Luke Smith | posted @ Sunday, January 17, 2010 3:47 PM | Feedback (0)

Reading Geek Night Presentation slides


I recently gave a 15minute presentation covering the SOLID Principles at the Reading Geek Night, not enough time to go into each principle but hopefully enough that people went away with some understanding of the principles and were encouraged to learn more about them.

I highly recommend watching this video of "UncleBob" at the Norwegian Developers Conference 2009 on SOLID Principles of OO class design

I’ve also uploaded my slides of my presentation to slideshare.

author: Luke Smith | posted @ Wednesday, December 09, 2009 7:51 PM | Feedback (0)

Now using github


I've decided to move my open source projects over to github, rather than hosting them on a private subversion server where they aren’t very accessible.

From what I've seen, and heard, github is a great source control repository, I only hope there is a visual studio addin as good as visualsvn in the pipeline.

Currently my 2 JavaScript libraries have been moved over

  • linq2js is a JavaScript library providing an api similar to that of linq in the .net framework. It features a near complete method for method implementation of those found on the IEnumerable interface as well as lazy evaluation of queries.
  • vegeojson is a helper utility i wrote for drawing shapes on a virtual earth (now bing) map given an object in the geojson format.

author: Luke Smith | posted @ Sunday, November 01, 2009 12:24 PM | Feedback (0)

aspnet RoleProvider woes with StructureMap and NHibernate


I just fixed a bug that has plagued me for the last 2 nights. NHibernate was throwing completely random exceptions, rolling back transactions with no real consistency other than always happening on requests made after the application had started and almost always within my RoleProvider. I couldn’t figure out what the heck was happening.

Some of the exceptions:

“Could not synchronize database state with session”

“Rollback failed - System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable.”

“Commit failed - System.NullReferenceException: Object reference not set to an instance of an object.”

“Could not synchronize database state with session - NHibernate.ADOException: There was a problem converting an IDataReader to NDataReader”

“System.ObjectDisposedException: Session was disposed of or closed Object name: 'ISession'.”

I’m using StructureMap to Dependency Inject an NHibernate.ISession into my NHibernateRepositoryBase class, and inject the repository to my Service class. Because you can’t dependency inject into a AspNet RoleProvider I’m using the StructureMap ObjectFactory.GetInstance<T> to get me an instance of my IUserService. I was placing this in the constructor, setting a private field that was then accessed in all the overridden methods I am implementing.

And this was what got me.

The reason that the exceptions would happen on any requests made after the application had started was because AspNet Providers are created once per application and reused throughout the duration of the application. This meant when the instance was created it would have a reference to the NHibernate.ISession for that request, but since the ISession is closed in application_endrequest subsequent requests the RoleProvider was now referencing an ISession that was closed.

My solution was to remove the ObjectFactory.GetInstance<T> field assignments to within each method that needed the service, that way ensuring that the NHibernate.ISession for the current request would be used.

author: Luke Smith | posted @ Wednesday, June 24, 2009 11:06 PM | Feedback (2)

ASUS Eee PC 1000HE Review


I’ve been on the lookout for a netbook for a few months. I’ve been tempted by the HP Mini-Note 2133, Dell Mini 9 and Dell Mini 10. Each had things I liked about them but none made me part with my cash.

The Dell Mini 9 looks great, but after seeing it in the shops and being able to get my hands on it the keyboard was far too small for me. So when the Dell Mini 10 was announced I thought “great, a larger screen and larger keyboard so it should be OK” but unfortunately you can’t upgrade the RAM, so you’re stuck at 1GB, not enough to comfortably run Windows 7.

In the end I was looking at the Asus Eee PC 1000H which lead my to spot the 1000HE. With a whopping 9.5 hours battery life, 1.66GHz Intel Atom CPU (the 1000H comes with a 1.6GHz), 10” screen, 120GB HDD, built in 1.3MP camera and multi touch trackpad temptation became too much. So I ordered one, along with a new 2GB stick of RAM to replace the standard 1GB.

First impressions were good, it looks great, it’s not too heavy and the screen is nice and bright. I booted up with the default XP installation to check that everything was working and then proceeded to install the Windows 7 Beta released a few months back.

Installing Windows 7 was amazingly quick, taking about 30-40 minutes in total (I installed via hosting the ISO image using the Microsoft Virtual CD-ROM utility under XP).

Windows 7 had no problems finding drivers, except for the LAN driver (you can download the XP driver from the ASUS website that works under Windows 7). Everything “just works”. CPU usage is currently sitting around 20% with Outlook, Live Writer, twhirl and IE8 open.

The keyboard isn’t full size, but is perfectly big enough even for my large hands. The only issue, as with getting any new keyboard, is the placement of some keys, Home/End/PgUp/PgDn are all function keys, which is annoying. It’s nothing that a few days of use won’t solve, so my fingers memorise the locations.

The one thing which I wish was present was a nipple. I really hate trackpads to control the mouse cursor. They can’t cost much to include, and theres enough room in the keyboard for one to be put. However I do like the multitouch functionality of the trackpad, especially for vertical scrolling.

Battery life appears excellent, I seem to be getting about 7 hours out of it with the wireless card turned on.

My next task was to install some software, Office 2007 and Visual Studio 2008, which because I don’t have an external DVD drive I had to do via sharing the DVD drive on my desktop over the network. VS2008 took about an hour, which tends to be the usual amount of time. However when installing Visual Studio 2008 SP1 I began getting issues with the graphics drivers, the machine became unusable and unresponsive with the graphics flickering and disappearing every few seconds. I left the install to run and it completed after about 2 hours.

Overall I’m very happy with the device. Netbooks are the perfect device for throwing in your rucksack for use when commuting, which I do alot of, and so the battery life is a real bonus with the Eee PC 1000HE. Windows 7 is perfect for netbooks, hopefully by RTM there will be some more performance boost and the graphics drivers will be improved.

Technorati Tags: ,

author: Luke Smith | posted @ Saturday, March 21, 2009 5:03 PM | Feedback (4)

Generating and enforcing that any link and request is lowercase with ASP.NET MVC


This post is based off 2 other blog posts I found which helped me come up with my solution with some slight modifications on their code. For my new project I’m having my URLs all lowercase, as some search engines interpret ‘/Home’ and ‘/home’ as two different locations. So the problem became “how can I enforce all my URLs get rendered as lowercase, and how do I force a request to a URL with an uppercase letter to redirect to the lowercase equivalent?”. Because I’m using ASP.NET MVC I needed a way to get the Routing engine to render the URL as lowercase when using an ActionLink. Asking the question over on stackoverflow I got a solution that involved creating my own class that inherits from Route, which I’ve called LowercaseRoute, and overrides the GetVirtualPath method. I also created a MapLowercaseRoute extension method on the RouteCollection class that allows me to map a LowercaseRoute easily.
public class LowercaseRoute : Route
{
public LowercaseRoute(string url, IRouteHandler routeHandler)
: base(url, routeHandler)
{
}

public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
: base(url, defaults, routeHandler)
{
}

public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
: base(url, defaults, constraints, routeHandler)
{
}

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
var virtualPath = base.GetVirtualPath(requestContext, values);

if (virtualPath != null)
{
virtualPath.VirtualPath = virtualPath.VirtualPath.ToLowerInvariant();
}

return virtualPath;
}
}
Next up is to ensure that any request to the site is enforced to be lowercased, and perform a 301 redirect if not. For this I’ve created a HttpModule, EnforceLowecaseRequestHttpModule, which I then register in the web.config. I could have put this directly into the global.asax file but I wanted to make it easily reusable on future projects.
public class EnforceLowercaseRequestHttpModule : IHttpModule
{
public void Dispose()
{
}

public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
}

private void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;

// If upper case letters are found in the URL, redirect to lower case URL (keep querystring the same).
string requestedUrl = ((application.Context.Request.Url.Scheme + "://" + application.Context.Request.Url.Authority + application.Context.Request.Url.AbsolutePath));

if (Regex.IsMatch(requestedUrl, @"[A-Z]") == true)
{
string lowercaseUrl = requestedUrl.ToLower();
lowercaseUrl += HttpContext.Current.Request.Url.Query;

application.Context.Response.Clear();
application.Context.Response.Status = "301 Moved Permanently";
application.Context.Response.AddHeader("Location", lowercaseUrl);
application.Context.Response.End();
}
}
}

author: Luke Smith | posted @ Sunday, February 01, 2009 6:02 PM | Feedback (3)