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.