Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

13 September 2011

Fun with enum

If you’ve done any vaguely serious programming with a pre-4 version of the .NET Framework then chances are you’ve had to write an Enum.TryParse() method. You probably wrote something like this:

public static bool TryParse<TEnum>(string value, out TEnum enumValue)
{
 Type enumType = typeof(TEnum);
 if (!enumType.IsEnum) throw new ArgumentException("Type is not an enum.");
 
 enumValue = default(TEnum);
 
 if (Enum.IsDefined(enumType, value))
 {
  enumValue = (TEnum)Enum.Parse(enumType, value);
  return true;
 }
 
 return false;
}

Everything went fine until someone decided to pass in a string representing a value of the underlying type such as “0” at which point Enum.IsDefined() said no even though your enum looked like this:

public enum MyEnum
{
 Zero = 0, One, Two, Three
}

Enum.Parse() will accept “0” just fine but IsDefined() requires the value be of the correct underlying type so in this case you’d need 0 as an integer for it to return true. Doesn't that mean I now need to work out the underlying type and then do the appropriate Parse() method using reflection? Oh dear, looks like our nice generic solution may get rather complicated!

Fear not. Because we know our input type is a string and there are a very limited number of underlying types we can have there’s a handy framework method we can use to sort this out – Convert.ChangeType().

public static bool IsUnderlyingDefined(Type enumType, string value)
{
 if (!enumType.IsEnum) throw new ArgumentException("Type is not an enum.");
 
 Type underlying = Enum.GetUnderlyingType(enumType);
 
 var val = Convert.ChangeType(value, underlying, CultureInfo.InvariantCulture);
  
 return Enum.IsDefined(enumType, val);
}

ChangeType() is effectively selecting the correct Parse method for us and calling it, passing in our string and returning a nice strongly typed underlying value which we can pass into Enum.IsDefined(). So our TryParse now looks like this:

public static bool TryParse<TEnum>(string value, out TEnum enumValue)
{
 Type enumType = typeof(TEnum);
 if (!enumType.IsEnum) throw new ArgumentException("Type is not an enum.");
 
 enumValue = default(TEnum);
 
 if (Enum.IsDefined(enumType, value) || IsUnderlyingDefined(enumType, value))
 {
  enumValue = (TEnum)Enum.Parse(enumType, value);
  return true;
 }
 
 return false;
}

This exercise is somewhat contrived especially now Enum.TryParse is part of .NET 4.0 but the synergy of ChangeType and IsDefined is quite nice and a technique worth pointing out nonetheless.

Links

13 May 2011

Bulk upsert to SQL Server from .NET

or, “How inserting multiple records using an ORM should probably work”

Anyone familiar with .NET ORMs should know that one area they’re lacking in is where it comes to updating or inserting multiple objects at the same time. You end up with many individual UPDATE and INSERT statements being executed on the database which can be very inefficient and often results in developers having to extend the ORM or break out of it completely in order to perform particular operations. An added complication is that, where identities are being used in tables, each INSERT command the ORM performs must immediately be followed by a SELECT SCOPE_IDENTITY() call to retrieve the identity value for the newly inserted row so that the CLR object may be amended.

It’s possible to drastically improve on this by making use of a couple of features already supported in the .NET Framework and SQL Server and I’m hoping that a similar solution will feature in future releases of the major ORMs.

  • The .NET Framework’s SqlBulkCopy class allowing you to take advantage of BULK operations supported by SQL Server.
  • SQL Server temporary tables.
  • SQL Server 2008’s MERGE command which allows upsert operations to be performed on a table and in particular its ability, using the OUTPUT command, to return identities for inserted rows.

The process

The main steps of the process are as follows:

  1. Using ADO.NET create a temporary table in SQL Server whose schema mirrors your source data and whose column types match the types in the target table.
  2. Using SqlBulkCopy populate the temporary table with the source data.
  3. Execute a MERGE command via ADO.NET on the SQL Server which upserts data from the temporary table into the target table, outputting identities.
  4. Read the row set of inserted identities.
  5. Drop the temporary table.

So instead of n INSERT statements to insert n records that’s four SQL commands in all to insert or update n records.

There’s already a blog post on this technique that goes into more detail by Kelias which you can read here. The only part missing from Kelias’ post is the piece utilising the OUTPUT modifier to retrieve the inserted identities from the MERGE command. This is simply an additional line in the merge command e.g.

OUTPUT $action, INSERTED.$IDENTITY

and the small matter of reading those returned identities out of a SqlDataReader.

This is the crucial piece, however, as it is this which allows us to tie the inserted row back to the original CLR “entity” item that formed part of our source data. Updating our CLR object with this identity will allow us to save subsequent changes away as an UPDATE to the now existing database row.

Performance

I did some brief testing to get rough timings of this technique versus individual INSERT calls using a parameterised ADO.NET command. With a variety of numbers and sizes of rows from 100 to 10,000 and with row sizes from 1k to 10k roughly the upsert technique nearly always executed in less than half the time of the individual INSERT statements. For example, 1,000 rows of about 1k each took individual INSERTs an average of just over 500ms versus bulk upsert’s 150ms on my quite old desktop with not very much RAM.

That’s pretty cool considering the upsert could be performing either an INSERT or an UPDATE command in the same number of calls whereas if I were to factor that into the individual SQL statements method it would be a lot of extra commands to try an UPDATE and then check whether any rows had been affected etc.

Github project

I decided to have a go at wrapping the upsert technique up in a library which would automatically generate the SQL necessary for creating the temporary table and running the MERGE. I pushed an initial version of this SqlBulkUpsert project to github which can be found here:
https://github.com/dezfowler/SqlBulkUpsert

Usage would be something like this:

using (var connection = DatabaseHelper.CreateAndOpenConnection())
{
 var targetSchema = SqlTableSchema.LoadFromDatabase(connection, "TestUpsert", "ident");

 var columnMappings = new Dictionary<string, Func<TestDto, object>>
       {
        {"ident", d => d.Ident},
        {"key_part_1", d => d.KeyPart1},
        {"key_part_2", d => d.KeyPart2},
        {"nullable_text", d => d.Text},
        {"nullable_number", d => d.Number},
        {"nullable_datetimeoffset", d => d.Date},
       };

 Action<TestDto, int> identUpdater = (d, i) => d.Ident = i;

 var upserter = new TypedUpserter<TestDto>(targetSchema, columnMappings, identUpdater);

 var items = new List<TestDto>();

 // Populate items with TestDto instances
 
 upserter.Upsert(connection, items);

 // Ident property of TestDto instances updated
}

with TestDto just being a simple class like this:

public class TestDto
{
 public int? Ident { get; set; }
 public string KeyPart1 { get; set; }
 public short KeyPart2 { get; set; }
 public string Text { get; set; }
 public int Number { get; set; }
 public DateTimeOffset Date { get; set; }
}

In this TypedUpserter example we:

  1. define the schema of the target table either in code or by loading it from the database (shown in the example)
  2. define mappings from column names of the target to a lambda retrieving the appropriate property value from the TestDto class
  3. define an action to be called to allow setting the the new identity to a property of the DTO
  4. instantiate the Upserter and call Upsert() with a list of items and a database connection
  5. the identity properties of the TestDto instances will have been updated using the defined action so the CLR objects will now be consistent with the database rows.

Next step

The object model could probably do with some refinement and it needs lots more tests adding but it’s in pretty good shape so next I’m going to look at integrating it into Mark Rendle’s Simple.Data project which should mean that, to my knowledge, it’s the only .NET ORM doing proper bulk loading of multiple records.

25 November 2010

Adding a design mode to your MVC app

When developing websites you'll likely have ended up in the situation where you need to make some styling changes to a page that's buried deep within the site. If that page is at the end of a process such as registration or checkout then it can be extremely time consuming entering test data that passes validation in order to navigate to the correct page. Add to that the complexity of maybe needing to log in and also having to do the same thing on multiple browsers and things can get ridiculous. If you’re using the WebForms view engine then you have limited design time capability in Visual Studio but this isn’t satisfactory for ensuring cross-browser compatibility.

What's needed is a dumb version of the site which simply renders the views using a variety of data. Effectively you want to create a load of static pages, each with ViewData, Model etc set up so that they represent a different step in one of the real processes on the site. Using this version you’d be able to get to the correct page straight away, be able to refresh it quickly after making markup or CSS changes and be able to visit the page in all your test browsers. Ideally using this version of the site will require no authentication and it wont have any external dependencies like databases or web services that must be set up or configured.

We can use a set of different controllers to do this, each having some hard coded model data for example:

// A real controller may look like this... 
public class PeopleController : Controller
{
	public ActionResult Index()
	{
		List<Person> people = GetListOfPeopleFromDatabase();
		return View(people);
	}

	private List<Person> GetListOfPeopleFromDatabase()
	{
		// Do some data access
		
		return new List<Person>
			{
				new Person{ Name = "Runtime Person 1" },
				new Person{ Name = "Runtime Person 2" },
				new Person{ Name = "Runtime Person 3" },
			};
	}
}


// And our design time controller like this...
public class PeopleController : Controller
{
	[Description("Empty people list page")]
	public ActionResult EmptyList()
	{
		return View("Index", new List<Person>{});
	}

	[Description("People list page with 5 random people")]
	public ActionResult ListWithFivePeople()
	{
		return View("Index", new List<Person>
			{
				new Person
				{
					Name = "John Smith"
				},
				new Person
				{
					Name = "Betty Davis"
				},
				new Person
				{
					Name = "Steve Jobs"
				},
				new Person
				{
					Name = "Bill Gates"
				},
				new Person
				{
					Name = "John Carmack"
				},
			});
	}
}

This will work best if your model classes or, the data entity classes you're passing on to your views are dumb i.e. they don't try to do any database access when the view renders. If you already have your controllers in a separate assembly then it should be a relatively simple task to swap your design time ones in and use them instead. If however you have the standard MVC setup of controllers, views and models all in the same project and assembly then things are a bit more difficult.

At the very  least we want our design time controllers in a separate folder of our project, away from the real ones. The issue with this is that the default MVC controller factory will find them here anyway. Thankfully we don't need to implement an entire new factory, we can hide them from the default one by simply breaking with the convention it uses to identify them, the easiest way being not naming them "...Controller".

Home page

A nice to have in this "design" mode would be a default page which shows a list of links to all the actions of the design time controllers with descriptions for what each represents. This would be particularly useful when handing the markup and CSS over to a third party to be styled up as it allows them to quickly access each variation of each screen. You'd end up with something like this:

  • Products
    • List products
    • Search products
    • View product
    • Product category
  • Basket
    • Empty
    • Full
    • Saved
  • My Account
    • Addresses
    • Billing details
  • Home
  • Contact us

Variations

In addition to each individual view the design time functionality could also allow for variations of these pages e.g. logged in / logged out  views, special offer views, user customised views etc. Variations could be  defined on an action, a controller or on the whole site and rather than defining the particular data in each of these cases a transform function could be defined which is called before view render. This function could do work along the lines of setting IsAuthenticated booleans for the logged in / logged out case and possibly more complex operations otherwise.

This would allow a wide variety of viewable pages to be created without  needing to specifically define data in all those cases.

Proof of concept

I've put a quick proof of concept up on Github here:
https://github.com/dezfowler/MvcDesignMode

There's the main MvcDesignMode library and an example MVC app based on the standard template site which has few design time controllers named "...Designer" rather than "...Controller". When not in design mode this should prevent them ever being accidentally accessed provided you're using the default controller factory. I have the code to enable design mode in the App_Start of Global.asax.cs and it looks like this:

bool designMode = Convert.ToBoolean(ConfigurationManager.AppSettings["DesignMode"]);
if (designMode)
{
	DesignMode.Activate(typeof(HomeController));
}
else
{
	AreaRegistration.RegisterAllAreas();
	RegisterRoutes(RouteTable.Routes);
}

Here I'm just using a boolean configuration setting in web.config to turn the mode on and off but how you might choose to do it is up to you. If the design mode is activated the standard application startup stuff is skipped mainly because design mode uses a standard set of routes. Any links in your pages built using custom routes wont work correctly but the point of design mode isn't to be able to navigate around the site as normal it is that you can jump straight to a particular page in one click. I’m passing a type in to the Activate method simply to server as a pointer to the assembly where my design time controllers reside.

Once in design mode the design time controller factory hunts down the special controllers ending with "...Designer" and effectively indexes them pulling out action method names and also the text from a Description attribute defined on the methods. Using this index it builds up a special site map listing each controller and its action methods as links.

Conclusion

Have a look at the solution on Github or have a go implementing something similar yourself. On a number of recent projects I could see having a setup like this saving a lot of time and effort not just for styling and markup but probably developing simple JavaScript stuff as well. I'll definitely be using it myself in all my future MVC projects.

18 November 2010

Pretty print hex dump in LINQPad

Was messing around with byte arrays a lot in LINQPad this week and really wanted a pretty hex print of the contents of the array so wrote this:

public static object HexDump(byte[] data)
{
	return data
		.Select((b, i) => new { Byte = b, Index = i })
		.GroupBy(o => o.Index / 16)
		.Select(g => 
			g
			.Aggregate(
				new { Hex = new StringBuilder(), Chars = new StringBuilder() },
				(a, o) => {a.Hex.AppendFormat("{0:X2} ", o.Byte); a.Chars.Append(Convert.ToChar(o.Byte)); return a;},
				a => new { Hex = a.Hex.ToString(), Chars = a.Chars.ToString() }
			)
		)
		.ToList()
		.Dump();
}

You use it like this:

byte[] text = Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy dog");

HexDump(text);

...and it will produce output akin to:

hexdump

02 October 2010

The Null Object pattern and the Maybe monad

Dmitri Nesteruk’s recent post Chained null checks and the Maybe monad struck a chord with me as I had messed about with something similar for performing a visitor-esque operation. I’ve glanced at a few posts about monads in the past however this is the first time I’ve had a proper look at one of them.

The purpose of the Maybe monad is essentially to remove the need for null reference checking. If you try to perform some function on an object which turns out to be null you might get a null reference exception. If, however, you perform the function on a Maybe then if the object is null the function is never called. It’s particularly useful if you’re performing a long chain of functions on an object, any of which may return null. In these cases when the null is encountered the remainder of the chain is skipped resulting in more robust, better performing code.

The implementations in .NET that I could find vary quite widely:

One aspect shared by most of these implementations, and which was pointed out in the comments of Dmitri’s post, is that they still end up doing all the null checking, it’s just hidden away. They are treating the “nothing” state as a value, effectively just creating a Nullable<T> which wraps reference types and then checking the HasValue at the beginning of each method call. I think a more elegant solution to this is to use the Null Object pattern.

A Null Object is a special inert type derived from our real class or a common base class. Each method is overridden by a version which has no effect. By wrapping any non-null objects we encounter in an instance of our real type and any nulls in an instance of our inert type we can continually call the methods of these types without fear of null reference exceptions occurring. Moreover, once we receive our inert type from one of the method calls we’re calling the methods on that type so we don’t need null checks at the beginning of our methods as the implementations we’re calling will have no effect.

Example

// Simple testing class
class Node
{
	public int Number { get; set; }
	public Node Parent { get; set; }
}


// Arrange
Node node = new Node
{
	Number = 1,
	Parent = new Node
	{
		Number = 2,
		Parent = new Node
		{
			Number = 3
		}
	}
};

// Act
var third = node.Maybe()
	.Apply(n => n.Parent)
	.Apply(n => n.Parent)
	.Return();

// Assert
Assert.IsNotNull(third);
Assert.AreEqual(3, third.Number);

Here we've got a simple test class and object graph and our code is trying to return the grandparent of node. First we use the Maybe extension method to create the Maybe object after this we're calling methods on the Maybe object itself. The Apply method behaves like a Map method and applies the supplied Func to the subject of the Maybe, returning its result as a new Maybe object. The Return then unwraps the Maybe and returns the subject object if there is one. If any of the methods called on the Maybe object fail we'll end up with a null coming back from Return.

Implementation

The basic structure is an abstract Maybe class with two derived classes; ActualMaybe which contains the real implementation and NothingMaybe which is the Null Object type. The implicit operator on Maybe is where any null is handled.

public abstract class Maybe<T> where T : class
{
	public static readonly Maybe<T> Nothing = new NothingMaybe<T>();
 
	public static implicit operator Maybe<T>(T t)
	{
		return t == null ? Nothing : new ActualMaybe<T>(t);
	}
}

class ActualMaybe<T> : Maybe<T> where T : class
{
	readonly T _t;
	public ActualMaybe(T t)
	{
		if (t == null) throw new ArgumentNullException("t");
		_t = t;
	}
}

class NothingMaybe<T> : Maybe<T> where T : class
{

}

The implementation for Apply is as follows:

// Maybe<T> 
public abstract Maybe<TResult> Apply<TResult>(Func<T, TResult> func) where TResult : class;

// ActualMaybe<T>
public override Maybe<TResult> Apply<TResult>(Func<T, TResult> func)
{
	return func(_t);
}

// NothingMaybe<T>
public override Maybe<TResult> Apply<TResult>(Func<T, TResult> func)
{
	return Maybe<TResult>.Nothing;
}

Apply takes the map function func which operates on the type T and returns some other type TResult. Apply itself returns the Maybe of TResult.

The ActualMaybe implementation simply calls func passing _t, which is the contained object, and returns the result of func. There is more going on here though; first _t can't be null because of the check in the ActualMaybe constructor so we don't need a null check, second we return whatever comes out of func but because the method returns a Maybe of TResult the implicit cast takes place and any nul coming out of func is replaced.

The NothingMaybe implementation ignores func altogether and just returns a NothingMaybe of TResult using the static readonly Nothing field on Maybe<T>.

The ActualMaybe implementation of Return returns _t while the NothingMaybe implementation always returns null.

I’ve implemented a couple of other useful methods including Do(Action<T>), If(Predicate<T>), Cast<TResult>() and AsEnumerable() as well as several overloads.

Possibilities

I think this Null Object approach could be combined with the Visitor pattern to achieve some extensibility although I’m not entirely sure how it would work or whether it would even be necessary.

Another possible extension is some kind of Collect method which would allow you to cherry pick particular objects from a graph and then would return an IEnumerable over just those objects at the end.

Code

I’ve put the code up on Github here:
http://github.com/dezfowler/Monads

28 August 2010

Aggregate full outer join in LINQ

I’ve recently been working on adding a feature to Rob Ashton’s AutoPoco project, a framework which enables dynamic creation of Plain Old CLR Object test data sets using realistic ranges of values. Rather than explicitly defining sets of objects in code, loading them from a database or deserializing them from a file the framework allows you to pre-define the make-up of the data set and then automatically generates the objects to meet your criteria.

I had a requirement that, from some sets of possible values for particular properties of a type, I  needed to create an instance for every variation of those values. Defining all the variations manually would take along time, be difficult to maintain and error prone. Dynamic generation seemed the way to go and after checking with Rob whether this was already a feature of AutoPoco and finding out it wasn’t I proceeded to have a go at implementing a GetAllVariations method.

The principal problem here is that we need to perform an operation analogous to a SQL full outer join on n sets of values. For example, give the following type:

public class Blah
{
	public int Integer { get; set; }
	public string StringA { get; set; }
	public string StringB { get; set; }
}

and the possible values:

Integer: [ 1, 2, 3 ]
StringA: [ "hello", "world" ]
StringB: [ "foo", "bar" ]

the output should be 12 objects with the following property values:

# Integer StringA StringB
1 1 hello foo
2 1 hello bar
3 1 world foo
4 1 world bar
5 2 hello foo
6 2 hello bar
7 2 world foo
8 2 world bar
9 3 hello foo
10 3 hello bar
11 3 world foo
12 3 world bar

Achieving this using LINQ

A full outer join can be performed in LINQ as follows:

var A = new List<object>
	{
		1, 
		2,
		3,
	};

var B = new List<object>
	{
		"hello",
		"world",
	};

A.Join(B, r => 0, r => 0, (a, b) => new List<object>{ a, b }).Dump();

Note: I’m using the LINQPad Dump() extension method here.

Fairly straight forward, we just set the join values to zero which forces a set to be produced where every value in A is joined to every other value in B. Ordinarily the join result selector would create a new anonymous type but I’m creating a new List here for reasons that will become obvious in a second.

We don’t know in advance how many sets of values we’re going to have, the user may want to set values for two or twenty properties. We need to be able to perform this same join for n sets, we’ll be working with a collection of these value sets. We can achieve this by combining the join with an aggregate operation e.g.

List<List<object>> sources = new List<List<object>>
{
	new List<object>
	{
		1, 
		2,
		3,
	},
	new List<object>
	{
		"hello",
		"world",
	},
	new List<object>
	{
		"foo",
		"bar",
	},
};

sources.Aggregate(
 	Enumerable.Repeat(new List<object>(), 1),
	(a, d) => a.Join(d, r => 0, r => 0, (f, g) => new List<object>(f) { g })
).Dump();

Here sources could contain any number of List objects and those List objects, containing the raw property values, can also contain any number of items. The output of the operation will be an enumeration over every variation of the values in sources, each represented as a List (in this case containing three items, one for each of the sources). We seed the Aggregate with what we expect to get out i.e. an IEnumerable of List objects. Our aggregating function is our join operation with a slight modification, our result selector creates a new List containing the result of the previous join (f) and the uses the collection initializer syntax to add one additional item (g), from the current set of values being joined on.

A relatively complex operation reduced to, effectively, a one-liner using LINQ. Snazzy.

22 August 2010

Roll your own mocks with RealProxy

These days there are more than enough mocking frameworks to choose from but if you need something a bit different, or just fancy having a go at the problem as an exercise, creating your own is easier than you might think. You don’t need to go anywhere near IL generation for certain tasks as where are a couple of types in the Framework which can get us most of the way on their own.

.NET 4.0 has the DynamicObject class which can be used for this as it allows you to provide custom implementations for any method or property. However there is another class which has been in the Framework since 1.1 that can be used in a similar way.

RealProxy is meant for creating proxy classes for remoting however there’s no reason why we can’t make use of its proxy capabilities and forget the remoting part, instead providing our own mocking implementation. Lets look at a simple example.

If it looks like a duck but can't walk it's a lame duck

If you're using dependency injection and are writing your code defensively you'll probably have constructors which look something like this:

public MyClass(ISupplyConfiguration config, ISupplyDomainInfo domain, ISupplyUserData userRepository)
{
 if(config == null) throw new ArgumentNullException("config");
 if(domain == null) throw new ArgumentNullException("domain");
 if(userRepository == null) throw new ArgumentNullException("userRepository");
 // ...assignments...
}

The unit test for whether this constructor correctly throws ArgumentNullExceptions when it's expected to will require at least some implementation of ISupplyConfiguration and ISupplyDomainInfo in order to successfully test the last check for userRepository.

All we need here is something that looks like the correct interface; it needn't be a concrete implementation or work as, for these tests, all we need is for it to not be null. Here’s how we could achieve this with RealProxy and relatively little code.

First we create a class inheriting from the abstract RealProxy:

public class RubbishProxy : System.Runtime.Remoting.Proxies.RealProxy
{
 public RubbishProxy(Type type) : base(type) {}

 public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg)
 {
  throw new NotImplementedException();
 }

 /// <summary>
 /// Creates a transparent proxy for type <typeparamref name="T"/> and 
 /// returns it.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <returns></returns>
 public static T Make<T>()
 {
  return (T)new RubbishProxy(typeof(T)).GetTransparentProxy();
 }
}

That's all, effectively just the boiler plate implementation code for the abstract class with one constructor specified and a static generic method for ease of use. We can then use it in our test method like so:

[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ExampleRealWorldTest_EnsureExceptionOnNullConfig()
{
 var myClass = new MyClass(null, null, null);
}

[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ExampleRealWorldTest_EnsureExceptionOnNullDomain()
{
 var config = RubbishProxy.Make<ISupplyConfiguration>();
 var myClass = new MyClass(config, null, null);
}

[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ExampleRealWorldTest_EnsureExceptionOnNullRepository()
{
 var config = RubbishProxy.Make<ISupplyConfiguration>();
 var domain = RubbishProxy.Make<ISupplyDomainInfo>();
 var myClass = new MyClass(config, domain, null);
}

Not bad for one line of code. How about something more complex?

Making a mockery of testing

The Invoke method we overrode in RubbishProxy can perform any action we like including checking arguments, returning values and throwing exceptions. In mocking frameworks, the most common method of setting up this behaviour is using a fluent interface e.g.

[Test]
public void ReadOnlyPropertyReturnsCorrectValue()
{
	var mock = new Mock<IBlah>();
	mock.When(o => o.ReadOnly).Return("thing");
	var blah = mock.Object;
	Assert.AreEqual("thing", blah.ReadOnly);
}

Here the When call captures o.ReadOnly as an expression, determining which member was the invokation target and returning a Call object. The Call object is then used to set up a return value as in the example above, or to check the passed arguments (CheckArguments) or throw an exception (Throw). It can also be set up to ignore the call or, in the case of a method call, to apply any one of those previous behaviours to only when particular arguments are passed in.

[Test]
[ExpectedException(typeof(ForcedException))]
public void MethodCallThrows()
{
	var mock = new Mock<IBlah>();
	mock.When(o => o.GetThing()).Throw();
	var blah = mock.Object;
	int i = blah.GetThing();
}

[Test]
public void MethodCallValid()
{
	var mock = new Mock<IBlah>();
	mock.When(o => o.DoThing(5)).CheckArguments();
	var blah = mock.Object;
	blah.DoThing(5);
}

[Test]
[ExpectedException(typeof(MockException))]
public void MethodCallInvalid()
{
	var mock = new Mock<IBlah>();
	mock.When(o => o.DoThing(5)).CheckArguments();
	var blah = mock.Object;
	blah.DoThing(4);
}

Source code for the example mock framework is up on GitHub here:
http://github.com/dezfowler/LiteMock

11 August 2010

Model binding and localization in ASP.NET MVC2

When creating an MVC site catering for different cultures, one option for persisting the culture value from one page to the next is by using an extra route value containing some form of identifier for the locale e.g.

/en-gb/Home/Index
/en-us/Cart/Checkout
/it-it/Product/Detail/1234

Here just using the Windows standard culture names based on RFC 4646 but you could use some other standard or your own custom codes. This method doesn’t rely on sessions or cookies and also has the advantage that the site can be spidered in each supported language.

Creating a base controller class for your site allows you to override one of its methods in order to set your current culture. For example if you amend your route configuration to "{locale}/{controller}/{action}/{id}" you could do the following:

string locale = RouteData.GetRequiredString("locale");
CultureInfo culture = CultureInfo.CreateSpecificCulture(locale);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;

It's important to set both CurrentCulture and CurrentUICulture as ResourceManager, used for retrieving values form localized .resx files, will refer to CurrentUICulture whereas most other formatting routines use CurrentCulture.

Once our culture is set, when we output values in our views ResourceManager can pick up our culture specific text translations from the correct .resx file and dates and currency values will be correctly formatted. String.Format("{0:s}", DateTime.Now), with "s" being the format string for a short date, will produce mm/dd/yyyy for en-US versus dd/mm/yyyy for en-GB.

This isn't the end of the story however, the problem arises of where in the controller do you perform your culture setting. It can't happen in the constructor because the route data isn't yet available so instead we could put it in an override of OnActionExecuting. This will seem to work fine for values output in your views but you come across a gotcha within model binding. Create a textbox in a form which binds to a DateTime and you'll end up with the string value being parsed using the default culture of the server. Using the US and UK dates example where your server's default culture is US but your site is currently set to UK. If you try to enter a date of 22/01/2010 you'll get a model validation error because it's being parsed as the US mm/dd/yyyy and 22 isn't a valid value for the month. Model binding happens before OnActionExecuting so that's no good.

A bit of digging around in Reflector and the Initialize method comes out as probably the best candidate for this as it is where the controller first receives route data and it occurs before model binding. We end up with something like (exception handling omitted for brevity):

protected override void Initialize(RequestContext requestContext) 
{
    base.Initialize(requestContext);
    string locale = RouteData.GetRequiredString("locale");
    CultureInfo culture = CultureInfo.CreateSpecificCulture(locale);
    Thread.CurrentThread.CurrentCulture = culture;
    Thread.CurrentThread.CurrentUICulture = culture;
 }

Both model binding and output of values will now be using the correct culture.

18 July 2010

Creating a light-weight visitor, fluently in C#

In object-oriented programming a common problem is performing some conditional logic based on the type of an object at run-time. For example, one form you may come across is:

public void DoStuff(MemberInfo memberInfo)
{
 EventInfo eventInfo = memberInfo as EventInfo;
 if(eventInfo != null)
 {
  // do something
  return;
 }

 MethodInfo methodInfo = memberInfo as MethodInfo;
 if(methodInfo != null)
 {
  // do something
  return;
 }

 PropertyInfo propertyInfo = memberInfo as PropertyInfo;
 if(propertyInfo != null)
 {
  // do something
  return;
 }

 throw new Exception("Not supported.");
}

Drawbacks to this being you have to wrap the whole thing in a method to make use of the "bomb out" return statements and it's quite a lot of code repetition which, as I’ve talked about previously, I'm not a fan of. Another example is a dictionary type->operation lookup:

// set up some type to operation mappings
static readonly Dictionary<Type, Action<MemberInfo>> operations = new Dictionary<Type, Action<MemberInfo>>();

// probably inside the static constructor...
operations.Add(typeof(EventInfo), memberInfo => 
{
 EventInfo eventInfo = (EventInfo)memberInfo;
 // do somthing 
});
operations.Add(typeof(MethodInfo), memberInfo =>
{
 MethodInfo methodInfo = (MethodInfo)memberInfo;
 // do something
});
operations.Add(typeof(PropertyInfo), memberInfo =>
{
 PropertyInfo propertyInfo = (PropertyInfo)memberInfo;
 // do something
});

// use it like this...
Type type = memberInfo.GetType();
Type matchingType = operations.Keys.FirstOrDefault(t => t.IsAssignableFrom(type));
if(matchingType != null)
{
 operations[matchingType](memberInfo);
}

The major drawback with this method is that you have to use IsAssignableFrom otherwise it doesn't match inherited types. In fact, the above example doesn't work if you just look up the type of memberInfo directly because we'll get types derived from EventInfo etc, not those types themselves. We also still need to cast to the type we want to work with ourselves and enumerating the dictionary isn’t ideal from a performance point of view.

The GoF pattern for solving this is the visitor which I’ve blogged about in the past however this is rather heavy duty, especially if your "do something" is only one line. It is much more performant than the alternatives though, as it’s using low level logic inside the run-time to make the decision about which method to call, so that should be a consideration.

Then next best alternative to the proper visitor is the first ...as...if...return... form but we can wrap it up quite nicely with a couple of extension methods to cut down on the amount of code we have to write. Here’s a trivial example trying to retrieve the parameters for either a method or a property. Depending on the type we need to call a different method so we identify that method using a fluent visitor:

private Type[] GetParamTypes(MemberInfo memberInfo)
{
 Func<ParameterInfo[]> paramGetter = null;

 memberInfo
  .As<MethodInfo>(method => paramGetter = method.GetParameters)
  .As<PropertyInfo>(property => paramGetter = property.GetIndexParameters)
  .As<Object>(o => { throw new Exception("Unsupported member type."); });

 return paramGetter().Select(pi => pi.ParameterType).ToArray();
}

The As extension attempts to cast “this” as the type specified by the type parameter T and if successful calls the supplied delegate. The overload used in the example above will skip the remaining As calls once one has been successful. There is a second overload which takes a Func<T, bool> rather than an Action<T> and will continue to try the next As if false is returned from the Func. The last As call, by specifying Object as the type, is a catch all and allows providing a default implementation or catering for an error case as shown above. The extensions are implemented like so:

/// <summary>
/// Tries to cast an object as type <typeparamref name="T"/> and if successful 
/// calls <paramref name="operation"/>, passing it in.
/// </summary>
/// <typeparam name="T">Type to attempt to cast <paramref name="o"/> as</typeparam>
/// <param name="o"></param>
/// <param name="operation">Operation to be performed if cast is successful</param>
/// <returns>
/// Null if the object cast was successful, 
/// otherwise returns the object for chaining purposes.
/// </returns>
public static object As<T>(this object o, Action<T> operation)
 where T : class
{
 return o.As<T>(obj => { operation(obj); return true; });
}

/// <summary>
/// Tries to cast an object as type <typeparamref name="T"/> and if successful 
/// calls <paramref name="operation"/>, passing it in.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="o"></param>
/// <param name="operation">Operation to be performed if cast is successful, must return 
/// a boolean indicating whether the object was handled.</param>
/// <returns>
/// Null if the object cast was successful and <paramref name="operation"/> returned true, 
/// otherwise returns the object for chaining purposes.
/// </returns>
public static object As<T>(this object o, Func<T, bool> operation)
 where T : class
{
 if (Object.ReferenceEquals(o, null)) return null;

 T t = o as T;
 if (!Object.ReferenceEquals(t, null))
 {
  if (operation(t)) return null;
 }
 return o;
}

14 July 2010

UTC gotchas in .NET and SQL Server

After doing some work with DateTime recently I stumbled across the interesting behaviour that a DateTime which is DateTimeKind.Unspecified will be treated as a DateTimeKind.Local whenever you try to perform some operation upon it. You get an “unspecified” DateTime whenever you don’t explicitly say it is Utc or Local. This makes sense because, when you do the following, in most cases what you intended was to use local time:

DateTime d1 = new DateTime(2010, 07, 01, 12, 0 ,0, 0);

If the current timezone is UTC +01:00 here's what I get when working with the DateTime created above:

d1.Kind; // => Unspecified
d1; // => 01/07/2010 12:00:00
d1.ToUniversalTime(); // => 01/07/2010 11:00:00
TimeZoneInfo.Local.GetUtcOffset(d1); // => 01:00:00

Note it’s applied an offset when calculating the UTC value which as we can see for clarification is +1 hour.

If what we actually wanted was a UTC time we need to explicitly specify the kind e.g.

DateTime d2 = new DateTime(2010, 07, 01, 12, 0 ,0, 0, DateTimeKind.Utc);
DateTime d2 = DateTime.UtcNow;

If you need to work with timezones other than UTC or the system timezone then you'll want to use DateTimeOffset rather than DateTime.

SQL Server and SqlDataReader

Another interesting gotcha arising from this is that the SQL Server datetime data type is also timezone agnostic. Any datetime values retrieved through the SqlDataReader will be an “unspecified” kind DateTime. This means that, even if you're correctly using the C# DateTime.UtcNow or the SQL GETUTCDATE() to produce the values in the database, when you try to retrieve them they will be shifted incorrectly according to the local timezone. Yikes!

There are two ways to deal with this.

DateTime.SpecifyKind()

The first is in C# using DateTime.SpecifyKind():

DateTime d3 = DateTime.SpecifyKind(d1, DateTimeKind.Utc);
d3.Kind; // => Utc
d3; // => 01/07/2010 12:00:00
d3.ToUniversalTime(); // => 01/07/2010 12:00:00

Which could be wrapped up in an extension method for ease of use e.g.

public static class SqlDataReaderExtensions
{
 public static DateTime GetDateTimeUtc(this SqlDataReader reader, string name)
 {
  int fieldOrdinal = reader.GetOrdinal(name);
  DateTime unspecified = reader.GetDateTime(fieldOrdinal);
  return DateTime.SpecifyKind(unspecified, DateTimeKind.Utc);
 }
}

SQL Server 2008 datetimeoffset

If you're using SQL Server 2008 you have the option of using the datetimeoffset data type instead. This will store the +00:00 timezone internally and the SqlDataReader will then retrieve the value correctly as a DateTimeOffset. No need to muck about with Kind.

If you have an existing database using datetime you can CAST these as a datetimeoffset in your query which usefully uses an offset of +00:00 in this case. (It treats "unspecified" as UTC – tut!)

31 May 2010

JavaScript-style Substring in C#

One thing that really bugs me when writing code is having to use unnecessary extra constructs to avoid exceptions or useless default values emerging. One such situation is trimming a string to a particular length e.g.

string sentence = "The quick brown fox jumps over the lazy dog";
string firstFifty = sentence.Substring(0, 50);

I want the first 50 characters from the sentence but in this example we get an ArgumentOutOfRangeException because there aren’t 50 characters in sentence. Not too helpful and it's an easy mistake to make. To avoid the exception we have to do this:

firstFifty = sentence.Length < 50 ? sentence : sentence.Substring(0, 50);

Yikes! That’s a lot of extra rubbish when all I want is the equivalent of LEFT(sentence, 50) in SQL.

We can easily wrap this up in a "Left" method but chances are we’re going to need a “Right” too so instead we can go down the route JavaScript takes with its "slice" function. JavaScript’s string slice can take one integer argument which, if positive, returns characters from the start of the string and, if negative, returns characters from the end of the string. Adding an overload to allow it to take a padding character is probably sensible too. The end result looks like this:

firstFifty = sentence.Slice(50);
// "The quick brown fox jumps over the lazy dog"
	
string firstTen = sentence.Slice(10);
// "The quick "

string lastTen = sentence.Slice(-10);
// "e lazy dog"

firstFifty = sentence.Slice(50, '=');
// "The quick brown fox jumps over the lazy dog=============="

string lastFifty = sentence.Slice(-50, '=');
// "==============The quick brown fox jumps over the lazy dog"

A lot more concise and quite useful.

public static class StringExtensions
{
   /// <summary>
   /// Returns a portion of the String value. If value has Length longer than 
   /// maxLength then it is trimmed otherwise value is simply returned.
   /// </summary>
   /// <returns>
   /// String whose Length will be at most equal to maxLength.
   /// </returns>
   public static string Slice(this string value, int maxLength)
   {
      if (value == null) throw new ArgumentNullException("value");
      
      int start = 0;
      if (maxLength < 0)
      {
         start = value.Length + maxLength;
         maxLength = Math.Abs(maxLength);
      }
      return value.Length < maxLength ? value : value.Substring(start, maxLength);
   }
   
   /// <summary>
   /// Returns a portion of the String value. If value has Length longer than 
   /// length then it is trimmed otherwise value is padded to length with 
   /// shortfallPaddingChar.
   /// </summary>
   /// <returns>
   /// String whose Length will be equal to length.
   /// </returns>
   public static string Slice(this string value, int length, char shortfallPaddingChar)
   {
      if (value == null) throw new ArgumentNullException("value");
      
      string part = value.Slice(length);
      int abslen = Math.Abs(length);
      if(abslen > part.Length)
      {
         part = length < 0 ? part.PadLeft(abslen, shortfallPaddingChar) : part.PadRight(abslen, shortfallPaddingChar);
      }
      return part;
   }
}

25 May 2010

Silverlight 3 Behavior causing XAML error

A recent XAML error I received from a Silverlight Behavior had me going round in circles trying to find the cause for quite a while. I was getting an AG_E_PARSER_BAD_PROPERTY_VALUE in code similar to the following:

<canvas x:name="Blah">
   <i:Interaction.Behaviors>
      <myapp:SpecialBehavior Source="{Binding SomeProperty}" />
   </i:Interaction.Behaviors>
   ...
</canvas>

The error identified the myapp:SpecialBehavior line as the culprit but didn't give me any further information so I proceeded to try and debug the binding to see what was going wrong. This didn’t shed any light on the cause, the binding was being created fine – the error was occurring later on.

This had me stumped for a couple of hours – I even tried setting up Framework source stepping only to find that the Silverlight 3 symbols weren’t yet available. In the end I stumbled upon the answer by chance – looking at the Canvas class in Reflector I noticed that it didn’t inherit from Control, only FrameworkElement via Panel. A quick check of my Behavior code and I found this:

public class SpecialBehavior : Behavior<Control>

It was the Behavior itself that was invalid in the Interaction.Behaviors property due to the incompatible type parameter. I changed Control to FrameworkElement and everything started working fine.

16 May 2010

Running UI operations sequentially in Silverlight

I've been playing around with Silverlight recently and have come across a requirement of needing to wait for the UI to do something before continuing. For example I have a UI with elements such and an image and text bound to properties of a model object. When the model object changes the interface updates to reflect this change but I need to perform an "unload" transition just before the model changes and a "load" transition just after it had changes.

Instead of this:

before I want this:

after

The orange arrows representing the transitions.

I considered having BeforeChange and AfterChange events, hooking my transition storyboards up to them and then firing them in the model setter. The trouble with this is that the storyboards will be playing in a separate thread so as soon as the BeforeChange one starts our code will have moved on and fired the AfterChange one. The result will be that we'll never see the "before" transition which will ruin the whole effect.

Mike Taulty posted about this same issue in 2008 highlighting that, to achieve the correct result, we end up needing to chain our code together using the Completed events of our storyboards. His solution was using some classes to wrap this up and I've taken a similar approach apart from that I have the sequence defined fluently and included the option of using visual states rather than explicitly defined storyboards.

private Album CurrentAlbum
{
   get
   {
      return this.DataContext as Album;
   }
   set 
   {
      if (CurrentAlbum != value)
      {
         new Sequence()
            .GoTo(this, LayoutRoot, "VisualStateGroup", "AlbumUnloaded")
            .Execute(() =>
            {
               this.DataContext = value;
            })
            .GoTo(this, LayoutRoot, "VisualStateGroup", "AlbumLoaded")
            .Run();		
      }
   }
}

It ends up being a lot quicker to write the code and I think it's quite obvious by reading it what will happen. If the visual state group or states aren't defined then only the inner assignment occurs.

The source for the Sequence class is a bit big for this post so the gist is here: Sequence.cs 

Considerations

Deferred execution
The storyboard or visual state change Completed event we're waiting for may never happen - do we try to execute the next steps anyway? I’ve taken the approach of firing off the next step in the destructor of the class however it may make more sense to set some arbitrary timeout so if the transition hasn’t completed after say 10 seconds we fire off the next step anyway.
Reuse
Should we allow a sequence to be created once and then reused many times - we could have an overload of Run() that takes a context object and passes it on to each of the steps. Could run into issues with people using closures like I do in the example. I’ve stuck with single use in the class, throwing an exception if Run() is called a second time.

21 August 2008

Excluding particular derived types in NHibernate queries

Today I came across an NHibernate problem where I needed to select every instance of a particular base type and all its derived types from a database, apart from one particular derived type. Here is a trivial example:

public class Mammal {}
public class Dog : Mammal {}
public class Cat : Mammal {}
public class DomesticCat : Cat {}

In this case the problem was equivalent to selecting every mammal that isn't a domestic cat.

We're using the table per class hierarchy inheritance model in NHibernate which uses values in a discriminator column to determine which type is held in a particular row of the table.

Selecting the whole hierarchy is done like this:

In HQL:
IQuery q = sess.CreateQuery("from Mammal");
IList mammals = q.List();
In Criteria:
ICriteria crit = sess.CreateCriteria(typeof(Mammal));
List mammals = crit.List();

I then needed to be able to effectively add a WHERE discriminator <> 'DomesticCat' to the end of the query. I had a quick search for this special discriminator property and for a Criteria Expression for excluding a particular type but couldn't find either.

The Solution

I finally found the solution on the WHERE clause page of the HQL chapter in the NHibernate reference. There is a special property called class which you can test against a type name in HQL or an actual type in Criteria queries e.g.

In HQL:
IQuery q = sess.CreateQuery("from Mammal m where m.class != 'DomesticCat'");
IList mammals = q.List();
In Criteria:
ICriteria crit = sess.CreateCriteria(typeof(Mammal));
crit.Add( Expression.Not( Expression.Eq("class", typeof(DomesticCat)) ) );
List mammals = crit.List();

04 August 2008

Generic collections and inheritance

Update - 07/2010

Covariance and contravariance support in .NET 4.0 takes care of this problem without the need for casting. Here's the relevant MSDN page: Covariance and Contravariance in Generics

I stumbled upon a small annoyance today when trying to use a generic collection of type B where a generic collection of type A is expected where B inherits from A. With arrays this works fine and the elements are implicitly cast to the base type.

Here's a snippet compiler script which illustrates the problem - list-converter.txt.

In the script I'm using BaseType and InheritingType for A and B. The script initially shows the implicit cast taking place for an array of B objects on line 19. The ArrayTest method expects an array of A but is quite happy being called with an array of B.

public static void ArrayTest(BaseType[] bar) { ... }

InheritingType[] myArray = new InheritingType[]{ it1, it2 };
ArrayTest(myArray);

If we now look at the ListTest method and try running this section of code...

public static void ListTest(List<BaseType> bar) { ... }

List<InheritingType> myList = new List<InheritingType>();
myList.Add(it1);
myList.Add(it2);
  
ListTest(myList);

...we get an error...

Argument '1': cannot convert from 
'System.Collections.Generic.List<InheritingType>' to 
'System.Collections.Generic.List<BaseType>'

We get the same result if we try an explicit cast

ListTest((List<BaseType>)myList);

Obviously allowing an implicit conversion for generics in general doesn't make a lot of sense but for lists I think it does and it's a pain to have to convert from one generic collection type to another.

Solution

Thankfully, with the help of some generics (of all things) and the ConvertAll method of List there's quite an elegant solution to this problem, we can create ourselves a nice generic list converter, here's an example:

public class ListConverter<TFrom, TTo> where TFrom : TTo
{
 public static IEnumerable<TTo> Convert(IEnumerable<TFrom> from)
 {
  return Convert(new List<TFrom>(from));
 }
 
 public static List<TTo> Convert(List<TFrom> from)
 {
  return from.ConvertAll<TTo>(new Converter<TFrom, TTo>(Convert));
 }

 public static TTo Convert(TFrom from)
 {
  return (TTo)from;
 }
}

We use two type arguments, the type we're converting from, which will be B from the example above, and the type we're converting to, A. Notice also the where TFrom : TTo which enforces that B must inherit from A.

As we need the ConvertAll method of List we have a method that takes an IEnumerable and creates a new List. We also have the method that does the main ConvertAll on the List and the delegate which is passed to ConvertAll.

This allows us to create a type converter as we code without needing to mess about e.g.

ListTest(ListConverter<InheritingType, BaseType>.Convert(myList));

02 June 2008

"duplicate association path" bug in NHibernate Criteria API

This problem exists in Hibernate itself as well and, contrary to some comments I've seen in the bug tracker, I believe it is a bug in the Criteria API and not in HQL.

A trivial example

I have a Store type representing a shop which has a collection, Products, containing Product types the shop stocks e.g. "Golf Balls", "Bananas", "Hats" etc. I want to get all the stores who stock both Golf Balls and Hats.

In HQL this would be :

SELECT s 
FROM Store AS s 
INNER JOIN s.Products AS prod1
INNER JOIN s.Products AS prod2
WHERE prod1.Type = 'Golf Balls' 
   AND prod2.Type = 'Hats'

...pretty straight forward and works fine.

In Criteria API this would be:

IList stores = sess.CreateCriteria(typeof(Store))
   .CreateAlias("Products", "prod1")
   .CreateAlias("Products", "prod2")
   .Add( Expression.EqProperty("prod1.Type", "Golf Balls") )
   .Add( Expression.EqProperty("prod2.Type", "Hats") )
   .List();

...again straight forward and seems logical but this produces an error...

NHibernate.QueryException: duplicate association path Products

As I said, it seems like a pretty solid candidate for a bug and it's odd considering surely the meaning of CreateAlias is that I want to use the same association more than once so need to alias it to different labels.

Unfortunately there's no way to get around this issue if you need distinct association joins like the above example and looking at the NHibernate code it doesn't seem like an easy fix. If, however, you can apply your criterion or sorts to the same alias then there is a workaround.

Workaround

NoteThis only applies where you don't require distinct association joins.

If we take a look at this handy NHibernate API reference we see that the two implementing classes for ICriteria are NHibernate.Impl.CriteriaImpl and NHibernate.Impl.CriteriaImpl.Subcriteria.

CriteriaImpl is the root criteria you get calling CreateCriteria on ISession and Subcriteria you get with every call to CreateCrteria or CreateAlias on ICriteria.

First you need to retrieve the root CriteriaImpl for your working ICriteria. Your working ICriteria may be the root but if it isn't you need to recurse up through the Parent property until you reach the CriteriaImpl object.

CriteriaImpl has an IterateSubcriteria method which returns an IList of all its Subcriteria descendants. You can loop through this list checking the Parent and Path properties of each item. The Parent because the value of Path is relative and you're only interested in what will be sibling Subcriteria to the one you're about to add.

If you find a match you can retrieve its alias from the Alias property, otherwise you can add a new alias to your working ICriteria.

Update - Jan 2014

It seems this bug is still not fixed in NHibernate (or Hibernate for that matter) and that it may also affect the LINQ provider. The relevant issues links are:

I'm very tempted to have a go at fixing this myself given there still seem to be a few people struggling with it. Will post another update if I get anywhere.

21 May 2008

Implementation of the Visitor pattern using .NET Generics

In a recent post I discussed using the Visitor pattern to solve a lazy initialization problem in NHibernate. The example Visitor class in that post is tied to the base class of the class hierarchy it is dealing with so everywhere you need to use a Visitor class you'd need to define at least one of these Visitor classes and then possibly inherit from it to implement alternative functionality.

A better solution is to use .NET Generics to create the Visitor e.g.:

// Visitor for base type TBase
public class Visitor<TBase>
{

 // Delegate for type TSub which can be any subclass of TBase
 // that takes a parameter of type TSub
 public delegate void VisitDelegate<TSub>(TSub u) where TSub : TBase;
 
 // Dictionary to contain our delegates
 Dictionary<Type, object> vDels = new Dictionary<Type, object>();
 
 // Method to add a delegate for type TSub which can be any subclass of TBase
 public void AddDelegate<TSub>(VisitDelegate<TSub> del) where TSub : TBase
 {
  vDels.Add(typeof(TSub), del);
 }
 
 // Visit method for type TSub which can be any subclass of TBase
 // takes one parameter of type TSub, picks the right delegate
 // and executes it passing the parameter to it
 public void Visit<TSub>(TSub x) where TSub : TBase
 {
  if(vDels.ContainsKey(typeof(TSub)))
  {
   ((VisitDelegate<TSub>)vDels[typeof(TSub)])(x);
  }
 }
 
}

I've knocked up a quick Snippet Compiler demo here. The key parts are the Accept methods in the classes of the hierarchy...

public class Cat : Mammal
{
 ...
 public override void Accept(Visitor<Mammal> visitor)
 {
  visitor.Visit<Cat>(this);
 }
}

...and adding the actual work to be done by creating delegate for each of the types you want to "capture"...

// Our visitor on our base class which will do our type specific work
Visitor<Mammal> visitor = new Visitor<Mammal>();
string outerVar = "A variable from outside delegate";

// Add the work to be done for DomesticCat
visitor.AddDelegate<DomesticCat>(delegate(DomesticCat a){
 WL("Doing some DomesticCat specific work");
 WL(a.Age + ", " + a.Color + ", " + a.Name);
 WL(outerVar);
});

// Add the work to be done for Dog
visitor.AddDelegate<Dog>(delegate(Dog b){
 WL("Doing some Dog specific work");
 WL(b.Age + ", " + b.Color);
});

The visitor pattern is quite widely applicable in OO environments however, while this solution may not be ideal where you need the visitor class to have a lot more information about the task it is to perform, it is certainly preferable to a large if...else if...else... type construct you might otherwise use for small tasks.

16 May 2008

Implicit polymorphism and lazy collections in NHibernate

If you create a lazy loaded property or collection in NHibernate which can contain any type from a class hierarchy, for example by having mappings like this:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Mammal" table="Mammal">
    <discriminator column="mammal_type" type="String"/>
    ...
    <subclass name="Cat" discriminator-value="CAT">
      ...
      <subclass name="DomesticCat" discriminator-value="CAT-DOMESTIC">
        ...
      </subclass>
    </subclass>
    <subclass name="Dog" discriminator-value="DOG">
      ...
    </subclass>
  </class>
  <class name="Zoo" table="Zoo">
    ...
    <bag name="Animals">
      <key column="zoo_fkey"/>
      <one-to-many class="Mammal"/>
    </bag>
  </class>
</hibernate-mapping>

You'll find that on requesting your objects from your collection they will be of a special new type NHibernate has created, derived from your base class which in this case is "Mammal".

This is a real problem because it means that you can't perform is or as operations on it to determine which actual type it is and you can't cast it to access properties and methods of your derived types.

The solution is to use the Visitor pattern which is described in detail on this site with a couple of examples in C# on this site. Essentially it involves creating a class with a method which is overloaded for each of the types in your class hierarchy.

class MammalVisitor
{
  public void Visit(Cat c) { ... Cat operations ... }
  public void Visit(DomesticCat dc) { ... DomesticCat operations ... }
  public void Visit(Dog d) { ... Dog operations ... }
}

This "visitor" object is then passed to a method defined on the base class of your hierarchy and then subsequently overridden on each derived type.

class Mammal
{
  public virtual void Accept(MammalVisitor mv) { mv.Visit(this); }
  ...
}

class Cat : Mammal
{
  public override void Accept(MammalVisitor mv) { mv.Visit(this); }
  ...  
}

class Dog : Mammal
{
  public override void Accept(MammalVisitor mv) { mv.Visit(this); }
  ...  
}

These methods simply call the visitor's method passing this to it which in turn will automatically execute the correct overload.

Mammal m; // some unknown derived type of mammal
MammalVisitor mv = new MammalVisitor();
m.Accept(mv);

These overloaded methods can then perform your type specific functions. In the example above you have no knowledge of the type of Mammal that you have however when you call Accept the relevant code is automatically executed. If Mammal happens to be a Cat type then the Cat overloaded Visit method is called.

13 May 2008

Creating Views using XSL in ASP.NET MVC

There's something about Web Forms that never felt quite right to me; it all seemed a bit too much like a bodge that created more problems than it solved. I've been having a tinker with ASP.NET MVC for the past few days now and I'm really liking the way it all fits together; giving you clean separation between the layers and a means of passing data between them.

The View layer in MVC uses a very Classic ASP-esque markup for mixing code and HTML. Seems rather dirty but by this point any major processing should have been done and all that you'll need to do is render HTML with maybe some looping.

That being said if all we'll need to do by this point is some looping at the most then why not use an XSL transform instead?

XSL is well defined and established now with a load of tools out there for giving you a WYSIWYG view of your tranform as you build it. Plus as it is purely XML based it will likely be a lot easier for designers (the folk who we really want to build Views) to get to grips with.

A quick proof of concept

Step 1 - Create a model class for your XSL ViewData

This has simply an XmlDocument which will contain our serialized object and a string which will contain a path to our XSL file.

public class XslViewData
{
 private System.Xml.XmlDocument _doc;
 private string _xslPath;

 public XslViewData(System.Xml.XmlDocument doc, string xslPath)
 {
  _doc = doc;
  _xslPath = xslPath;
 }
  
 public System.Xml.XmlDocument Doc
 {
  get 
  {
   return _doc;
  }
 }

 public string XslPath
 {
  get
  {
   return _xslPath;
  }
 }
}

Step 2 - Serialize your object to XML in your Controller

First make sure the type you want to render is ready for XML serialization. This involves adding some attributes to classes and properties so read up on that first before you carry on. It's important to get your type serializing out in a nice way as it will be easier to work with in the XSL.

using System.Xml;
using System.Xml.Serialization;
...
Product prod = ProductRepository.GetProduct(id);
XmlSerializer ser = new XmlSerializer(typeof(Product));  
XmlDocument doc = new XmlDocument();
System.IO.MemoryStream ms = new System.IO.MemoryStream();
XmlWriter xw = XmlWriter.Create(ms);
ser.Serialize(xw, prod);
ms.Position = 0;
doc.Load(XmlReader.Create(ms));
RenderView("Xsl", new XslViewData(doc, "/Content/prodDetail.xsl"));

Step 3 - Create a ViewPage or ViewUserControl to host your XSL

All you need in the aspx/ascx file is an Xml ASP.NET control...

<asp:Xml ID="Xml1" runat="server" onload="Xml1_Load"></asp:Xml>

...and in the code behind...

public partial class Xsl : ViewPage<XslViewData>
{
 protected void Xml1_Load(object sender, EventArgs e)
 {
  Xml1.Document = ViewData.Doc;
  Xml1.TransformSource = ViewData.XslPath;
 }
}

Step 4 - Create an XSL file

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
 
 <xsl:template match="/Product">
  <h2><xsl:value-of select="Name"/></h2>
  <xsl:apply-templates select="Image"/>
    </xsl:template>

 <xsl:template match="Image">
  <img>
   <xsl:attribute name="src">
    <xsl:value-of select="ImageUrl"/>
   </xsl:attribute>
  </img>
 </xsl:template>
 
 <xsl:template match="*">
 </xsl:template>
 
</xsl:stylesheet>

Done

Not only is this simple to implement it has a lot of scope for improvment; compiling transforms, adding caching and configuation etc. This method also has the advantage that it requires no recompile to alter the template.

Links

16 February 2008

NHibernate in Visual Web Developer Express

If you fancy using NHibernate in VWD you'll have trouble because you can't compile your mapping files into the same assembly as your classes. As a result you can't add mappings to your session factory by assembly name or class name.

Thankfully there is a simple solution to this, which I'll demonstrate with the aid of the quickstart example in the NHibernate documentation.

Start by creating all your persistance class files in your App_Code folder with your mapping files (.hbm.xml) alongside. Next, make the alterations to your web.config as outlined in section 1.1 of the quickstart but leave out this line:

<mapping assembly="QuickStart" />

In your mapping files, change the assembly attribute of the root hibernate-mapping element to "App_Code" and remove the namespace attribute if you're not using a namespace (the default behaviour of VWD) e.g:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="App_Code">

Finally, copy the code for the NHibernateHelper class from section 1.4 and change its constructor from this:

static NHibernateHelper()
{
   sessionFactory = new Configuration().Configure().BuildSessionFactory();
}

to this:

static NHibernateHelper()
{
   Configuration cfg = new Configuration().Configure();
   cfg.AddDirectory(new System.IO.DirectoryInfo(HttpContext.Current.Server.MapPath(@"~/App_Code/")));
   sessionFactory = cfg.BuildSessionFactory();
}

The original constructor used the mapping element in the web.config to find out which mappings to load, here we're telling it to load all the mapping files it finds in the App_Code folder. You can also use the AddFile method to add individual mapping files.