2008-03-27

NHibernates MemCached feature

Getting started

NHibernate have rich support for caching, one of them is memcached. Getting started was actually easy, I followed this guide.

Download the sample

The VS2005 solution can be downloaded here. It is based on NHibernate NHibernate-1.2.1.GA-src.zip and SQL CE is included.

Using the sample

Memcahed Win32 is included in the solution and 2 instances can be started with memcached1.bat and memcached2.bat. Any activity can be monitored in the console windows.

NHibernate logs to a file called "NHibernateCacheExampleClient\log4net.log", and you should be able to see SQL executed against the database here.

The "Create" button creates a new Person with Id "1" and the name "John Doe". 
The "Get" button loads a Person with Id "1".

If the cache is running and the Person is in the cache, the NHibernate log should not show any SQL execute and the memcached console should show activity.

2008-03-26

NHibernates Search feature

Ayende wrote about Googlize your entities: NHibernate & Lucene.NET Integration, but the only documentation I could find was this blog post.

I have created a sample application, using the NHibernate NHibernate-1.2.1.GA-src.zip and build it with NAnt in release mode. It uses SQL CE, so everything is packed in the file.

Download it here

2008-03-21

TFS 2008 Build with WiX 3 - Keeping it clean

Its a good practise to keep the Build Box as clean as posible, that is dont install 3rd party dependencies.

To begin with you need to add WiX 3 to your Source Control, most peaple seen to have a "tools" folder or the like.

When Wix has been added, all you need to do is override the MSBuild properties WiX uses.

Check out the TFSBuild.rsp file and add the following.

# This is a response file for MSBuild
# Add custom MSBuild command line options in this file
/property:WixTargetsPath=..\..\..\tools\WiX\bin\Wix.targets
/property:WixTasksPath=WixTasks.dll
/property:WixToolPath=C:\projects\MyProject\Sources\tools\WiX\bin\
/v:diag

The paths might need some tweaking to fit your needs.

NHibernates SchemaUpdate feature

Ayende wrote about Setting Up Zero Friction Projects - Data Access, and mentioned the new SchemaUpdate feature in NHibernate.

The idea being that the ddl is automagically created from the nhibernate hbm.xml files, and executed against the delvelopers local database.

Something like:

  1. Developer A changes the Order.hbm.xml where he adds a new field Discount.
  2. In ApplicationStart the ddl alter script is generated and executed against Developer A's local database, the next time the developer starts the application.
  3. Developer eventually does a check-in of the Order.hbm.xml, along with the other changes.
  4. Developer B does a get latest.
  5. When he starts the application, ApplicationStart executes the change dll, and now Developer B's local database is up to speed.

At what cost? Well, almost zero :-)

I have created a sample C# VS2008 Solution, that can be downloaded here.

2008-03-06

When to throw an Exception

2 Golden rules of using Exceptions:

  1. Fail Fast
  2. Exceptions should be... well exceptional.

These two rules are contradicting, or are they?

Fail fast dictates that we should throw an exception, when an operation is used on an invalid state.

public class Customer
{
	private bool _authenticated;
	private Command _command;
	private Logger _logger;

	public Customer(bool authenticated, Command command, Logger logger)
	{
		_authenticated = authenticated;
		_command = command;
		_logger = _logger;
	}
}

First of all, we dont let the ctor do anything besides assigning fields. It does not throw exceptions ever! So basically we allow our object to be created in a potentially invalid state.

It is first when an operation is used on an invalid state, that we have to fail fast. And since we dont ever do any operations on object in our ctor, it will never throw an exception.

Methods use fields and arguments in two ways. They pass on the reference to the object or they operate on the object. Only throw exceptions if the method operates on the object.

public class Customer
{
	private bool _authenticated;
	private Command _command;
	private Logger _logger;

	public void PassOnLoggerToCommand()
	{
		//_command is operated on so throw if it is null
		//_logger is passed on as a reference, so do not throw.
		if(_command == null) throw new InvalidOperationException("command is null. Are you missing a dependency?");

		_command.SetLogger(_logger);
	}
}

If you throw an Exception from with in a method - not at the top of the method -, that is a good indication that you need to refactor the method into two.

public class Customer
{
	private bool _authenticated;
	private Command _command;
	private Logger _logger;

	public void Execute()
	{
		if(!_authenticated)
		{
			//Exception throw inside the method (BAD)
			if(_logger == null) throw new InvalidOperationException("logger is null. Are you missing a dependency?");
			_logger.Info("Attempted login...");
		}
		else
		{
			//Exception throw inside the method (BAD)
			if(_command == null) throw new InvalidOperationException("command is null. Are you missing a dependency?");
			_command.Execute();
		}
	}
}

Can be refactored to.

public class Customer
{
	private bool _authenticated;
	private Command _command;
	private Logger _logger;

	public void Execute()
	{
		if(!_authenticated)
		{
			LoggerInfo("Attempted login...");
		}
		else
		{
			ExecuteCommand();
		}
	}

	private void ExecuteCommand()
	{
		//Exception throw at the top of the method (GOOD)
		if(_command == null) throw new InvalidOperationException("command is null. Are you missing a dependency?");

		_command.Execute();
	}

	private void LoggerInfo(string message)
	{
		//Exception throw at the top of the method (GOOD)
		if(_logger == null) throw new InvalidOperationException("logger is null. Are you missing a dependency?");
		
		_logger.Info(message);
	}
}

Exceptions should be exceptional, and there are performance implications of throwing an exception, so what to do?

Make a query method on the class that checks that a given operation can be made with the current state. So that you never have to catch Exceptions that you create in your own code.

public class Customer
{
	private Command _command;

	public Customer(Command command)
	{
		_command = command;
	}

	public void ExecuteCommand()
	{
		if(!CanExecuteCommand) throw new InvalidOperationException("command cannot be executed given the current state.?");

		_command.Execute();
	}

	public bool CanExecuteCommand()
	{
		return _command != null
	}
}

Try to make the queries simple questions that return a bool. You might find it that the queries also help when writing automated tests.

A final note, beware of threading issues when using queries.