Sunday, June 3, 2012

Dependency Injection for RouteConstraints


Often I've wanted to check whether something exists in the database in a route constraint, unfortunately MVC doesn't support dependency injection for RouteConstraints out of the box, and due to them being alive for the entire life of the application it isn't that easy. If the scope of the dependency is in request scope, for example, then it will work for the first request then not for every request after that.

You can get around this by using a very simple DI wrapper for your route constraints.

public class InjectedRouteConstraint<T> : IRouteConstraint where T : IRouteConstraint
{
private IDependencyResolver _dependencyResolver { get; set; }
public InjectedRouteConstraint(IDependencyResolver dependencyResolver)
{
_dependencyResolver = dependencyResolver;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return _dependencyResolver.GetService<T>().Match(httpContext, route, parameterName, values, routeDirection);
}
}
then create your routes like this
var _dependencyResolver = DependencyResolver.Current; //Get this from private variable that you can override when unit testing
routes.MapRoute(
"Countries",
"countries/{country}",
new {
controller = "Countries",
action = "Index"
},
new {
country = new InjectedRouteConstraint<CountryRouteConstraint>(_dependencyResolver);
}
);
view raw createroutes.cs hosted with ❤ by GitHub

 
var _dependencyResolver = DependencyResolver.Current; //Get this from private variable that you can override when unit testing
routes.MapRoute(
"Countries",
"countries/{country}",
new {
controller = "Countries",
action = "Index"
},
new {
country = new InjectedRouteConstraint<CountryRouteConstraint>(_dependencyResolver);
}
);
view raw routes.cs hosted with ❤ by GitHub

My StackOverflow Post