Tuesday, November 30, 2010

ASP.NET MVC: Creating a URL From Route Values

I’m currently building some JSON services for a client using ASP.NET MVC. One of the things I want to implement is HATEOS (read the link) so I need to be able to build the URLs (or URIs) of the endpoints that I can then embed into the JSON I return to the client.

I wanted to be able to take some route values, controller=”abc”, action=”xyz”, id=10, and return a virtual path. Unfortunately System.Web.Routing makes this a bit of trial, but you can make it work. I’ve wrapped my implementation up in a little UriBuilder class. Here’s a test showing it working:

[Test]
public void CreateUriFromRouteValues_should_create_the_correct_virtual_path()
{
var routes = new RouteCollection();
routes.MapRoute(
"ProgRock",
"{band}/{album}/{track}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });

var uriBuilder = new UriBuilder(() => routes, () => new FakeHttpContext());

var uri = uriBuilder.CreateUriFromRouteValues(new
{
band = "Yes",
album = "Fragile",
track = "Roundabout",
info = "great keyboard solo"
});

uri.ShouldEqual("/Yes/Fragile/Roundabout?info=great%20keyboard%20solo");
}

And here’s the implementation:

public interface IUriBuilder
{
string CreateUriFromRouteValues(object values);
}

public class UriBuilder : IUriBuilder
{
private readonly Func<RouteCollection> getRouteCollection;
private readonly Func<HttpContextBase> getHttpContext;

public UriBuilder(Func<RouteCollection> getRouteCollection, Func<HttpContextBase> getHttpContext)
{
this.getRouteCollection = getRouteCollection;
this.getHttpContext = getHttpContext;
}

public string CreateUriFromRouteValues(object values)
{
var routeValues = new RouteValueDictionary(values);

var routeData = new RouteData();
var requestContext = new RequestContext(getHttpContext(), routeData);
var virtualPathData = getRouteCollection().GetVirtualPath(requestContext, routeValues);
if (virtualPathData == null)
{
throw new ApplicationException("virtualPathData is null");
}
return virtualPathData.VirtualPath;
}
}

In order to unit test it, you have to fake the HttpContext. Here’s my fake implementation:
 
public class FakeHttpContext : HttpContextBase
{
public override HttpRequestBase Request
{
get { return new FakeRequest(); }
}

public override HttpResponseBase Response
{
get { return new FakeResponse(); }
}
}

public class FakeRequest : HttpRequestBase
{
public override string ApplicationPath
{
get { return "/"; }
}
}

public class FakeResponse : HttpResponseBase
{
public override string ApplyAppPathModifier(string virtualPath)
{
return virtualPath;
}
}

You can also use the fake HttpContext if you want to be able to create URLs outside an ASP.NET application where HttpContext.Current is null.

In the application, I register my route and httpContext provider delegates like this:

public class MvcInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<Func<HttpContextBase>>()
.Instance(() => new HttpContextWrapper(HttpContext.Current)),
Component.For<Func<RouteCollection>>()
.Instance(() => RouteTable.Routes)
);
}
}

Sammy.JS

I’ve been looking at Sammy.JS recently. It’s a lightweight Javascript framework for managing transitions on your page. It extends jQuery. The neat trick it uses is to leverage the anchor part of the URI – that’s the bit after the ‘#’ to provide routes into your javascript. If you’ve used the new routing framework in ASP.NET you’ll understand it straight away.

Here’s a quick example I’ve put together. We’ve got three links with three paragraphs. As you click the links the related paragraph appears.

This is the first paragraph.

This is the second paragraph.

This is the third paragraph.

The big deal is that I now have a URI to each paragraph and normal browser functions like the back button work. Go on, you can try it. I can correctly link straight to a particular state of my Ajax application, and you know what a PITA that can be.

Here’s the code for the page:

<html>
<head>
<title>Sammy Test</title>
<script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="sammy.js" type="text/javascript"></script>
<script src="sammy_test.js" type="text/javascript"></script>
</head>
<body>
<div id="header">
<h1>Sammy Test</h1>
<a href="#/one">one</a>
<a href="#/two">two</a>
<a href="#/three">three</a>
</div>
<div id="main">
<p id="one">This is the first paragraph.</p>
<p id="two">This is the second paragraph.</p>
<p id="three">This is the third paragraph.</p>
</div>
</body>
</html>

And here’s the script:

(function($) {

var app = $.sammy('#main', function() {

var hideAll = function() {
$("#one").hide();
$("#two").hide();
$("#three").hide();
};

this.get('#/', function(context) {
hideAll();
});

this.get("#/one", function(context) {
hideAll();
$("#one").show();
});

this.get("#/two", function(context) {
hideAll();
$("#two").show();
});

this.get("#/three", function(context) {
hideAll();
$("#three").show();
});
});

$(function() {
app.run('#/');
});

})(jQuery);

If you are writing even a slightly complicated Ajax application it’s worth checking Sammy out.

Saturday, November 20, 2010

Pedant Corner: Clarifying IoC, DIP and DI

There were quite a few comments on my last post telling me that I was confusing the following terms:

  • Inversion of Control
  • Dependency Inversion (Principle)
  • Dependency Injection

So I thought I’d attempt to clarify things. Check out this Wikipedia article:

http://en.wikipedia.org/wiki/Inversion_of_control

"Inversion of Control is highly associated with dependency injection and the dependency inversion principle. Dependency injection is the main method to implement Inversion of Control."

As I understand it Inversion of Control and the Dependency Inversion Principle are both different names for the same 'principle' of OO design. That you should decouple your software by depending on abstractions rather than implementations.

Dependency Injection is a 'pattern' used to implement Inversion of Control/Dependency Inversion. This is either implemented as constructor injection, where dependencies are ‘injected’ via constructor parameters, or as property injection where dependencies are injected via property setters.

This is just my understanding of these terms. If you think I’m wrong please comment and maybe we can arrive at some accepted definitions.

Thursday, November 18, 2010

The first Commandment: Thou shalt not reference the IoC container!

I recently received a very nice email asking about one of my ‘10 Advanced Windsor Tricks’ posts where I’d stated, without really backing it up:

“Without this trick you would have to reference the container itself, which is an IoC anti-pattern of epic proportions.”

So why is referencing the IoC container an anti-pattern?

The hint is the name 'Inversion of Control'. IoC a is core principle of OO design, the idea being that you don't depend on concrete implementations, but on abstractions (in our case, interfaces). We want to build our software like Lego, out of independent components, that supply to their environment all the information about what they need to work. That information is described in interfaces. When we have a service like this:

public class MyService : ISomeService
{
    public MyService(ISomeDependecy someDependency) {
    }
}

… it's telling us two things, firstly that it supplies a service described by the ISomeService interface, that is, anywhere where an ISomeService is required, MyService can be supplied. The second thing it tells us is that it requires ISomeDependency to work. It doesn't care how that's implemented, just that whatever is supplied obeys that contract.

The important point here is that MyService is described entirely in terms of it’s own domain. Inversion of Control is a principle not a technology. We don’t need a container at this stage.

Now if I'm referencing a container I've lost that information:

public class MyService: ISomeService
{
    public MyService() {
        var someDependency = StaticContainer.Resolve<ISomeDependency>();
    }
}

You might argue that the container is what it needs to in order to function, but we're really lying here, we could be using any dependency internally and it's not communicated to the outside world. Rather than describing our component in terms of its own domain, we’re polluting it with infrastructure concerns (the container).

By doing this you are making your life harder than it needs to be. Say I want to write a unit test for MyService, I now have to mock IContainer and get it to pass some mock of ISomeDependency, it's twice as much work. So not only have I lost information, I've made my own life as a developer harder.

But the most important message that this kind of code is carrying, is that the author has failed to grasp the real genius of IoC containers. I’ll try an example:

Say I have these components:

class Component1 : IComponent1
{
    Component1(IComponent2 component2) { ... }
}

class Component2 : IComponent2
{
    Component2(IComponent3 component3) { ... }
}

class Component3 : IComponent3

They are all registered with my IoC container. Now when I resolve IComponent1 like this:

var component1 = container.Resolve<IComponent1>();

the container will first create an instance of Component3, then an instance of Component2 passing it the Component3 instance in its constructor. Then finally it will create an instance of Component3 passing the Component2 instance to its constructor which it returns to the caller.

Deep inside our infrastructure, there is a single call to the container to get the root object of our application (our core application class if you will), all the cascading dependencies from that root object are discovered, constructed and supplied by the container. That's the magic of IoC containers, they glue our application together, but you never see them except for that initial, single resolve call.

So referencing the container itself is an anti-pattern of epic proportions, because it means you’ve failed to understand what an IoC container is. It's a bit like buying a tractor, hitching it up to a team of horses and attempting to plow a field with it.

Monday, November 08, 2010

Tardis Bank at £5App

Here’s a video of me presenting Tardis Bank at £5App last week. It was late in the evening and we’d all had a few beers, so it’s worth watching just for the heckling :) Many thanks to Ian Ozsvald for sharing this. The whole evening was excellent, it’s well worth checking out the other videos on Ian’s blog.

£5 App #23 - Mike and the Tardis Bank from Ian Ozsvald on Vimeo.

Friday, November 05, 2010

An ASP.NET HttpModule to set the current culture to the user’s locale

Update: sandord, in the comments, has pointed out that you can achieve the same result with a simple configuration setting in Web.config:

<globalization culture="auto" uiculture="auto" enableClientBasedCulture="”true”" />

My web application TardisBank (a pocket money bank account for kids) needs to show users the currency symbol for their location. So UK users should see ‘£’, but US users should see ‘$’. I’d thought that I would have to ask the user to choose a currency symbol when they signed up, but Dylan Beattie had a much better idea:

dylan_twitter_recommends_locale_from_request

A quick Google turned up this excellent article by Rick Strahl, ‘detecting and setting the current locale on the current asp.net web request’.

Using Rick’s code I quickly created an ASP.NET module:

using System;
using System.Globalization;
using System.Threading;
using System.Web;

namespace Suteki.TardisBank.Mvc
{
    public class UserLocaleModule : IHttpModule
    {
        public void Init(HttpApplication httpApplication)
        {
            httpApplication.BeginRequest += (sender, eventArgs) =>
            {
                var app = sender as HttpApplication;
                if (app == null)
                {
                    throw new ApplicationException("Sender is null or not an HttpApplication");
                }
                var request = app.Context.Request;
                if (request.UserLanguages == null || request.UserLanguages.Length == 0) return;

                var language = request.UserLanguages[0];
                if (language == null) return;

                try
                {
                    Thread.CurrentThread.CurrentCulture = new CultureInfo(language);
                }
                catch
                {}
            };
        }

        public void Dispose()
        {
            
        }
    }
}

Which I configured in TardisBank’s web.config:

<modules runAllManagedModulesForAllRequests="true">
  <add name="UserLocale" type="Suteki.TardisBank.Mvc.UserLocaleModule, Suteki.TardisBank" />
</modules>

And now I’ve got currency symbols :)

tardisbank_currency_gbp

And if I change my browser’s language settings:

tardisbank_change_language_settings

I now get the $ symbol instead:

tardisbank_currency_usd

Thanks Dylan & Rick! It’s a very neat solution.

Composing Sequential Tasks With Linq

This is a continuation of my Task Parallel Library investigations. Yesterday I wrote about using TPL with MVC.

Say we have a number of asynchronous tasks that we want to execute in series because the result of the first task is an input value to the second task, and the result of the second task is an input to the third. To demonstrate, I’ve created two simple task generators:

static Task<int> CreateInt(int a)
{
    return Task<int>.Factory.StartNew(() =>
    {
        Console.WriteLine("Starting CreateInt   {0}", a);
        Thread.Sleep(1000);
        Console.WriteLine("Completing CreateInt {0}", a);
        return a;
    });
}

static Task<int> AddInts(int a, int b)
{
    return Task<int>.Factory.StartNew(() =>
    {
        Console.WriteLine("Starting AddInts     {0} + {1}", a, b);
        Thread.Sleep(1000);
        Console.WriteLine("Completing AddInts   {0} + {1}", a, b);
        return a + b;
    });
}

I want to create an int and then add 3 to it, and then add 4. It’s difficult to compose these using the standard ‘ContinueWith’ callback:

public void ComposeWithContinueWith()
{
    var result = CreateInt(2)
        .ContinueWith(t1 => AddInts(t1.Result, 3)
            .ContinueWith(t2 => AddInts(t2.Result, 4))
            );

    // result is the first task, how do you get the third task's result?
}

You can simply put two lots of ‘Unwrap()’ at the end of the expression:

public void ComposeWithContinueWith() { var result = CreateInt(2) .ContinueWith(t1 => AddInts(t1.Result, 3) .ContinueWith(t2 => AddInts(t2.Result, 4)) ).Unwrap().Unwrap();

Console.WriteLine("Completed with result {0}", result.Result); }

But there is a much nicer way. But because tasks are Monadic, you can compose them using Linq:

Update / Correction: The out-of-the-box Task<T> doesn’t have Linq methods (SelectMany etc) built in.

However, there is an implementation in the ParallelExtensionsExtras assembly. I confused myself (it happens a lot) because I’d included the ParallelExtensionsExtras for the Task extension methods on SmtpClient and SqlDataReader, and has simply assumed that Task<T> has the Linq extension methods built in.

You can build the ParallelExtensionsExtras.dll yourself from the Samples for Parallel Programming. Alternatively, you can just grab a compiled ParallelExtensionsExtras.dll from my sample solution at: https://github.com/mikehadlow/Suteki.AsyncMvcTpl. Stephen Toub has a great write up on the goodies in the Parallel Extensions Extras library here, it’s a great read.

Anyway, so once you have a reference to ParallelExtensionsExtras, you can compose Tasks using Linq expressions:

public void CanComposeTasksWithLinq()
{
    var result = from a in CreateInt(2)
                 from b in AddInts(a, 3)
                 from c in AddInts(b, 4)
                 select c;

    Console.WriteLine("Completed with result {0}", result.Result);
}

Which outputs:

Starting CreateInt   2
Completing CreateInt 2
Starting AddInts     2 + 3
Completing AddInts   2 + 3
Starting AddInts     5 + 4
Completing AddInts   5 + 4
Completed with result 9

This is a really nice pattern to use if you have a number of async IO tasks to do in series.