Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ninject injection based on a route data value

We've got an ASP.NET MVC application, that has a number of different areas. There are 2 areas that use the same C# classes from our service layer, but target different underlying data. I want these services to get different dependencies based on a value in the route data.

It's hard to explain, and I'm paraphrasing my class/area names. To illustrate: Call logic

When the 'Code' is in the route data, I want to get different dependencies injected to when it is not present.

I understand there is the .When() method you can use to do conditional bindings, but I'm not sure how to get the route data from there. I could possibly also do it based on the area that it was called from, however thats not preferable in my instance (I think we may use the Code in that other area)

Is this possible?

like image 372
RodH257 Avatar asked Nov 03 '22 15:11

RodH257


1 Answers

This works for me (it is for standard route configuration "{controller}/{action}/{id}")

Ninject configuration

protected override Ninject.IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Bind<IService>()
        .To<ServiceA>()
        .When(x => IsRouteValueDefined("id", null));
    kernel.Bind<IService>()
        .To<ServiceB>()
        .When(x => !IsRouteValueDefined("id",null));
    return kernel;
}
// just sample condition implementation
public static bool IsRouteValueDefined(string routeKey, string routeValue)
{
    var mvcHanlder = (MvcHandler)HttpContext.Current.Handler;
    var routeValues = mvcHanlder.RequestContext.RouteData.Values;
    var containsRouteKey = routeValues.ContainsKey(routeKey);
    if (routeValue == null)
        return containsRouteKey;
    return containsRouteKey && routeValues[routeKey].ToString() == routeValue;
}

it will use

  • ServiceA for routes: /home/index/1, /home/index/2 etc.
  • ServiceB for routes: / , /home/index etc.
like image 148
mipe34 Avatar answered Nov 09 '22 14:11

mipe34