I have moved my active blog over to tumblr. I've maintained this blog for reference but will be posting to http://www.robustsoftware.co.uk instead. I've pointed my Feedburner feed to tumblr so if you're subscribed already you should already have switched with me.

Strongly typed links for ASP.NET MVC through the power of LINQ expressions

Wouldn't it be nice if you could have strongly typed links in your ASP.NET MVC views rather than a having to use floaty strings? Something like this for example:


    1 <%= Html.LinkTo<ProjectsController>("Settings", c => c.Index()) %>



Or something similar with an id argument?


    1 <%= Html.LinkTo<ProjectsController>(ViewData.Model.Name, c => c.Details(ViewData.Model.Id)) %>



Well utilising the awesomeness of LINQ expressions, generics and extension methods (that's right, 3 kinds of awesome, at the same time) you can:


    1 public static string LinkTo<TController>(this HtmlHelper helper, string linkText,

    2     Expression<Func<TController, ActionResult>> action) where TController : IController

    3 {

    4     object routeValues;

    5 

    6     var methodExpression = action.Body as MethodCallExpression;

    7     var actionName = methodExpression.Method.Name;

    8     var controllerName = methodExpression.Object.Type.Name.Replace("Controller", string.Empty);

    9 

   10     // is there an id parameter on the action method being called?

   11     if (methodExpression.Method.GetParameters().Where(p => p.Name == "id").SingleOrDefault() != null)

   12     {

   13         // yes - retrieve the value of the id through magicks

   14         var idPropertyExpression = methodExpression.Arguments[0];

   15         var id = Expression.Lambda(idPropertyExpression).Compile().DynamicInvoke();

   16 

   17         routeValues = new { controller = controllerName, id };

   18     }

   19     else

   20     {

   21         routeValues = new { controller = controllerName };

   22     }

   23 

   24     return helper.ActionLink(linkText, actionName, routeValues);

   25 }



So what's going on here?

On lines 1 and 2 we are defining a generic signature for an extension of the HtmlHelper class which can only be used by implementations of IController (the interface which all ASP.NET MVC controllers must implement). This extension method takes two arguments, the text to display for the link and an Expression for a call to one of the actions on the controller.

So what does this buy us?

Well by casting the body of the Expression as a MethodCallExpression (line 6) we can gain access to the name of the method being called (line 7) and the name of the controller (line 8).

We can then look further at the method being called to see if it has a parameter with the name "id" (line 11). If there is such a parameter we begin to descend into the witchcraft of expression trees.

Firstly we grab the node of the expression tree which is used for the "id" parameter which we are assuming will be the first parameter (line 14). We can then use this node's Expression to create a LambdaExpression (line 15) which then means we can compile and invoke the node to retrieve the value the Expression represented. The way that this works allows you to use any statement that will produce an integer value within the expression. Either a property on an object as in the example or a regular integer will work.

We use the values we have retrieved from the Expression to create an anonymous type to be passed to the regular ActionLink extension. If there is no "id" parameter we will just create an anonymous type with only a value for the controller.

These are then passed to the regular ActionLink method but we have been hidden from all the floaty string nastiness.

Please note, this isn't a complete solution, more a proof of concept.

Clearing the cache of a LINQ to SQL DataContext

I was having some problems with my test code in that the DataContext was returning the objects from the cache (even though it was querying the database) and this was skewing my integration tests. Through the use of Reflector I found that there actually is a method for clearing the cache, handily called ClearCache(). However, the method was internal and so could not be called directly from code.

Internal methods are, however, available through reflection (I'm a bit of a noob when it comes to reflection so there might be constraints on when they are and when they aren't but this works for me). In order to make it easy to clear the cache (for example, after saving but before retrieving the object from the database for checking it saved correctly) I have created an extension method to do the heavy lifting for me:

public static void ClearCache(this ProjectSupportContext context)

{

    const BindingFlags FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

 

    var method = context.GetType().GetMethod("ClearCache", FLAGS);

 

    method.Invoke(context, null);

}

Hope this helps someone else out with LINQ to SQL caching woes.

Making LINQ to SQL associations perform inner joins

Today I had a problem whereby I had created an association but when the data for my object was retrieved it was joining the tables through a left outer join.

As these joins were non-nullable I wanted to make them perform an inner join to take advantage of the greater performance. In order to do this you need to set the ForeignKey attribute to "true" and CanBeNull to "false". The omission or reversal of either of these attributes will mean LINQ to SQL will assume that the parent object may not exist and will instead perform a left outer join

This will mean you end up with a XML mapping such as:

<Association Name=”SomeAssociation” Member=”Project” ThisKey=”ProjectId”
OtherKey=”Id” ForeignKey=”true” CanBeNull=”false” />

Of course you also need to create a DataLoadOption so that the parent object gets retrieved along with the child (eagerly):

var options = new DataLoadOptions();

options.LoadWith<Job>(j => j.Project);

context.LoadOptions = options;

ASP.NET MVC: Strongly typing form methods with input values

Recently I've had the opportunity to use the latest MVC drop to create a web site that is more than just a play thing. Along my travels I found an annoying problem with using the Html.Form helper. I wanted to call this action:

Action

If I wanted to let the framework automatically map values from my form to the action's parameters I was unable to strongly type the action URL using the Html.Form helper. This forced me to use code such as:

FormBefore 

Now this meant that I was heavily dependant on strings to tie everything together properly. The controller, action and form value mapping was dependent on it. This felt a bit nasty, but it worked.

The reason I could not use the existing strongly type lambdas was that the action required arguments and in order to use the existing lambdas you have to supply arguments for all the parameters. This is possible with for the Verify action by supplying dummy values:

DefaultLambda

This would work for my simple example. However, it relies on the userName and password arguments not being mapped in your routing rules. If you wanted a value such as id to be selected from a drop down using this method would hard code in the id which isn't what you want.

I thought there must be some way round this using a combination of generics, reflection and LINQ so I used the existing generic method as a starting point and got an understanding of how it used Expressions and Funcs to tie things together. From this I figured there must be a way to create an expression pointing at my action which I'd then be able to interrogate to grab the values I wanted.

At this point I must thank Daniel Cazzulino and Ayende Rahien for their fantastic posts on getting methods from expressions and static reflection respectively. These helped me work out the code which did the hard stuff without having to know absolutely everything about Expressions and Funcs.

Through the use of an Expression we can create a form helper which looks like this:

NewLambda

Though quite verbose, this has allowed us to strongly type the action to be called and the type of its parameters (this will generate a URL for the form of /Home/Verify). I believe this type safety is a great improvement on the bunch of strings we started off with.

Here's how the magic happens:

HelperExtensions

It works by taking the Expression that is passed to it to get a MethodInfo object which has the details of our Action. From the MethodInfo object we can grab the name of the action and the name of its controller, passing it in to the existing Html.Form helper method. Through a generic constraint we can ensure that this method can only be used for an IController and that the method called must return an ActionResult object.

From this single method it is simply a case of writing a bunch of overrides so that you can have all the control over the form available in the existing helpers (i.e. setting the form method and passing in a dictionary of values). There is a limit of 3 on the number of parameters that this can currently handle due to the limit on arguments that a Func can take. There may be a way to work around this but it is beyond my needs so I have not looked into it.

I couldn't find a decent way to host the source so drop me a line if you want it, or even better let me know where I could host it for free without people having to suffer pop ups or general eye spam.

File.Create and the mysterious IOException

I was putting together a bunch of unit tests today for a program that's managing the transfer, etc. of a bunch of files. I created an extension method to make it easy to add empty files to directories for my tests (code requires the System.IO namespace to be imported):

public static void CreateEmptyFile(this DirectoryInfo directory, string fileName)
{
    File.Create(Path.Combine(directory.FullName, fileName));
}

However, everything was going fine with my tests until I started trying to move files about. Whenever I wanted to move a file I would get an IOException with the message "The file is already in use". My files were being created as I expected, just I could not move them without an exception being thrown. Going over and over the code I could not see where the problem is coming from.

Eventually after bashing my head against a wall for a while I decided to go over everything from the beginning. What I had missed is that File.Create is not a method but a function which returns a FileStream. So the problem was that this FileStream was left hanging around and so I could not do anything with the file.

Once I had realised that the fix was easy, close the stream:

public static void CreateEmptyFile(this DirectoryInfo directory, string fileName)
{
    File.Create(Path.Combine(directory.FullName, fileName)).Close();
}

Hope this helps someone see the wood from the trees and not waste time looking for a simple mistake.

Will code generation reduce the quality of my code?

Recently we've been evaluating code generation tools and helpers like Resharper and Code Rush. We've focused more on Code Rush as it has equal capabilities for both VB and C# and we deal with both languages, Resharper is much more focused on C#.

Though the tools help you write more code faster, I have this niggling question in the back of my mind: is this really a good thing? I can't help feeling that I'm missing out on some tactile experience with the code if I'm not typing every character of it. I find that if writing out the code for a class is a chore then I'll stand back and rethink whether I'm actually doing the best thing. Literally feeling the pain in my fingers of possibly poor code.

If that crap code is easy to write, will I not feel the pain and leave potentially crap code in my software?

I'll also miss out on the down time whilst I'm cranking out code that I let my BackgroundWorker think about the wider ideas.

Is it possible to code too fast, or are my fears unfounded?

kick it on DotNetKicks.com

Creating a company library

I've recently been thinking about how I could encourage the development team I am part of to further their knowledge and therefore help the entire team to advance and produce better software.

Though blogs are good for sound bytes and quick heads ups, I believe you can't get better than a good book for helping you grasp new tools and concepts. I try to lend people books I've bought and enjoyed to share the knowledge and to be able to discuss the contents and therefore gain a deeper understanding.

However, I think that many developers, though they want to read, never get round to actually buying the books. There's always bills to pay, food to buy, beer to drink, games to play and I can't really blame them, that's how I thought until recently.

This has led me to the idea of a company library, one that could just be formed from the books owned by the developers that are lent within the company but in my opinion it would be much better if there was some level of buy-in from the company itself. This would lower the access level to the company's developers to the resources they need.

The library should be given a monthly budget (something like £50 would be enough for 1-2 books depending on size, though obviously the more the better) and a lead developer take the librarian role and would be in charge of the purchasing of books and keeping tabs on where they are. Any developer could submit requests for new books but the librarian would have final say. This would mean that they could buy resources to help with an upcoming project utilising a new technology when the need arose.

I don't think that you would need to allot company time for reading the books, the developers should use their own free time to read the books. The company is providing the books free of charge and though the aim is to improve the company, that will be achieved by the developers improving their personal skills which would increase their value as a developer in the job market.

To double my suggested minimum budget to £100 a month, that would cost the company £1200 a year which is less than the cost of a weeks course for a single developer yet you build up a permanent resource which is available for the entire team.

Also, if you are a .NET shop, don't necessarily limit your library to .NET books, expand to books on general development as books of this type are language agnostic and throw in the odd book on design to improve the way your better written software looks!

Why not try and get a company library set up where you work?

kick it on DotNetKicks.com

More fluent assertions using extension methods

I'm a great believer in making your unit tests as easy to read and understand as possible. I was thinking about how I could improve my tests the other day and thought about using extension methods to create a more fluent way of creating complex assertions.

This has allowed me to create a complex assertion like:

  1. testObject.ShouldBeTheSameObjectAs(targetObject).And.ShouldBeEqualTo(testObject).And.ShouldSatisfy(x => x is Object);

Which I hope you'll agree reads a lot easier than those three assumptions on separate lines. Also, note that I have added the ability to use a predicate for when there isn't a method which quite matches your needs.

Here's the code for the extension methods:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using MbUnit.Framework;
  6.  
  7. namespace UnitTestingExtensions
  8. {
  9.     public static class FluentTestingExtensions
  10.     {
  11.         public static FluentAnd<T> ShouldSatisfy<T>(this T testTarget, Predicate<T> predicate)
  12.         {
  13.             Assert.IsTrue(predicate.Invoke(testTarget));
  14.             return new FluentAnd<T>(testTarget);
  15.         }
  16.  
  17.         public static FluentAnd<T> ShouldBeEqualTo<T>(this T testTarget, T comparisonObject)
  18.         {
  19.             Assert.AreEqual(testTarget, comparisonObject);
  20.             return new FluentAnd<T>(testTarget);
  21.         }
  22.  
  23.         public static FluentAnd<T> ShouldBeTheSameObjectAs<T>(this T testTarget, Object comparisonObject)
  24.         {
  25.             Assert.AreEqual(testTarget, comparisonObject);
  26.             return new FluentAnd<T>(testTarget);
  27.         }
  28.  
  29.         public class FluentAnd<T>
  30.         {
  31.             public T And { get; private set; }
  32.  
  33.             public FluentAnd(T target)
  34.             {
  35.                 this.And = target;
  36.             }
  37.         }
  38.     }
  39.  
  40. }

And here are the tests for the extension methods:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using MbUnit.Framework;
  6.  
  7. namespace UnitTestingExtensions.FluentTestingExtensionsTests
  8. {
  9.     [TestFixture]
  10.     public class ShouldSatisfyTests
  11.     {
  12.         [Test, ExpectedException(typeof(MbUnit.Core.Exceptions.AssertionException))]
  13.         public void PredicateEvaluatesAsFalseAndTestFails()
  14.         {
  15.             int testNumber = 4;
  16.  
  17.             testNumber.ShouldSatisfy(x => x > 10);
  18.         }
  19.  
  20.         [Test]
  21.         public void PredicateEvaluatesAsTrueAndTestPasses()
  22.         {
  23.             int testNumber = 4;
  24.  
  25.             testNumber.ShouldSatisfy(x => x == 4);
  26.         }
  27.     }
  28.  
  29.     [TestFixture]
  30.     public class ShouldBeEqualToTests
  31.     {
  32.         [Test, ExpectedException(typeof(MbUnit.Core.Exceptions.AssertionException))]
  33.         public void EqualsCheckFailsAndTestFails()
  34.         {
  35.             int testNumber = 4;
  36.  
  37.             testNumber.ShouldBeEqualTo(7);
  38.         }
  39.  
  40.         [Test]
  41.         public void EqualsCheckPassesAndTestPasses()
  42.         {
  43.             int testNumber = 4;
  44.  
  45.             testNumber.ShouldBeEqualTo(4);
  46.         }
  47.     }
  48.  
  49.     [TestFixture]
  50.     public class ShouldBeTheSameObjectAsTests
  51.     {
  52.         [Test, ExpectedException(typeof(MbUnit.Core.Exceptions.AssertionException))]
  53.         public void DifferentObjectsSoTestFails()
  54.         {
  55.             Object testObject = new Object();
  56.  
  57.             testObject.ShouldBeTheSameObjectAs(new Object());
  58.         }
  59.  
  60.         [Test]
  61.         public void TestPassesWhenTheObjectsAreTheSame()
  62.         {
  63.             Object testObject = new Object();
  64.             Object checkObject = testObject;
  65.  
  66.             testObject.ShouldBeTheSameObjectAs(checkObject);
  67.         }
  68.     }
  69.  
  70.     [TestFixture]
  71.     public class AndTests
  72.     {
  73.         [Test, ExpectedException(typeof(MbUnit.Core.Exceptions.AssertionException))]
  74.         public void TestFailsIfFirstCaseFails()
  75.         {
  76.             int testNumber = 4;
  77.  
  78.             testNumber.ShouldBeEqualTo(3).And.ShouldSatisfy(x => x > 1);
  79.         }
  80.  
  81.         [Test, ExpectedException(typeof(MbUnit.Core.Exceptions.AssertionException))]
  82.         public void TestFailsIfSecondCaseFails()
  83.         {
  84.             int testNumber = 4;
  85.  
  86.             testNumber.ShouldBeEqualTo(4).And.ShouldSatisfy(x => x > 10);
  87.         }
  88.  
  89.         [Test]
  90.         public void TestPassesIfBothCasesPass()
  91.         {
  92.             int testNumber = 4;
  93.  
  94.             testNumber.ShouldSatisfy(x => x > 1).And.ShouldBeEqualTo(4);
  95.         }
  96.  
  97.         [Test]
  98.         public void TestPassesWhenThreeCasesAreUsed()
  99.         {
  100.             Object testObject = new Object();
  101.             Object targetObject = testObject;
  102.  
  103.             testObject.ShouldBeTheSameObjectAs(targetObject).And.ShouldBeEqualTo(testObject).And.ShouldSatisfy(x => x is Object);
  104.         }
  105.     }
  106. }

I'd love to hear some feedback on what you think of this style.

My version of a SmartBag

After seeing Jeffrey Palermo's SmartBag (part 1 and part 2) I was inspired to create my own version which was more specific to my needs. For one I'm a lover of the IEnumerable<T> interface, especially when combined with the power of LINQ for Objects.

Anyway, enough of my waffle, here's the code for the class.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections;
  4. using System.Text;
  5.  
  6. namespace SmartBag
  7. {
  8.     public class SmartBag
  9.     {
  10.         private Hashtable _hashtable;
  11.  
  12.         public SmartBag()
  13.         {
  14.             this._hashtable = new Hashtable();
  15.         }
  16.  
  17.         public void Add<T>(T item)
  18.         {
  19.             List<T> list;
  20.  
  21.  
  22.             if (!this._hashtable.ContainsKey(typeof(T)))
  23.                 this._hashtable.Add(typeof(T), new List<T>());
  24.  
  25.             list = this._hashtable[typeof(T)] as List<T>;
  26.             list.Add(item);
  27.         }
  28.  
  29.         public IEnumerable<T> Get<T>()
  30.         {
  31.             if (!this._hashtable.ContainsKey(typeof(T)))
  32.                 throw new IndexOutOfRangeException(string.Format("There are no entries for {0}", typeof(T).Name));
  33.  
  34.             foreach (T item in this._hashtable[typeof(T)] as List<T>)
  35.                 yield return item;
  36.         }
  37.     }
  38. }

There are basically two methods to it, Add and Get. Add adds items of the specified type to a list of that type. Get retrieves the list of the specified type.

Below are my test cases which should give you some ideas of how you can use it.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using MbUnit.Framework;
  6.  
  7. namespace SmartBag
  8. {
  9.     [TestFixture]
  10.     class SmartBagTest
  11.     {
  12.         [Test]
  13.         public void AClassAddedAgainstAnInterfaceCanBeRetrievedTogether()
  14.         {
  15.             SmartBag bag = new SmartBag();
  16.  
  17.  
  18.             bag.Add<IContract>(new Parent());
  19.             bag.Add<IContract>(new Child());
  20.  
  21.             Assert.AreEqual(2, bag.Get<IContract>().Count());
  22.         }
  23.  
  24.         [Test]
  25.         public void AChildWillBeAddedToItsParentsEnumerationIfYouDefineIt()
  26.         {
  27.             SmartBag bag = new SmartBag();
  28.  
  29.  
  30.             bag.Add(new Parent());
  31.             bag.Add<Parent>(new Child());
  32.  
  33.             Assert.AreEqual(2, bag.Get<Parent>().Count());
  34.         }
  35.  
  36.         [Test, ExpectedException(typeof(IndexOutOfRangeException))]
  37.         public void AnExpectionWillBeRaiseWhenAttemptingToRetrieveATypeThatDoesNotExist()
  38.         {
  39.             SmartBag bag = new SmartBag();
  40.  
  41.  
  42.             foreach (Object item in bag.Get<Object>()) { } // must enumerate for it to be evaluated
  43.         }
  44.  
  45.         [Test]
  46.         public void ShouldBeAbleToAddChildAsADifferentType()
  47.         {
  48.             SmartBag bag = new SmartBag();
  49.  
  50.  
  51.             bag.Add(new Parent());
  52.             bag.Add(new Child());
  53.  
  54.             Assert.AreEqual(1, bag.Get<Parent>().Count());
  55.             Assert.AreEqual(1, bag.Get<Child>().Count());
  56.         }
  57.  
  58.         private class Parent : IContract
  59.         {
  60.         }
  61.  
  62.         private class Child : Parent
  63.         {
  64.         }
  65.  
  66.         private interface IContract
  67.         {
  68.         }
  69.     }
  70. }

To begin with this is a basic idea. I hope to utilise it in an upcoming project and it will probably look a bit different after I've used it in anger. Something I can see I might need is to extract an interface to make testing easier but I've left that out for now as YAGNI may apply.

Any feedback would be greatly appreciated.