MVC请求的Ninject上下文绑定

时间:2013-02-11 23:54:47

标签: c# dependency-injection ninject

我有一个不寻常的情况将服务注入ASP.NET MVC控制器。 Controller提供单个动作来呈现页面上的侧栏菜单,注入Controller的服务是创建侧栏内容的工厂。该操作使用[ChildActionOnly]属性进行修饰:只有在渲染其他操作时才能呈现侧栏。

困难在于我想根据请求的页面(= Controller)注入侧栏工厂抽象的不同实例。以前,我使用的是一种抽象工厂,它使用控制器名称字符串来确定要使用的具体工厂实现的不优雅实现;我现在把它移到一个合适的抽象工厂,因此需要将工厂类型的选择移到别处。

我的Ninject绑定目前非常简单地定义为:

Kernel.Bind<ISideBarFactory>().To<FooSideBarFactory>().InRequestScope();
Kernel.Bind<ISideBarFactory>().To<DefaultSideBarFactory>().InRequestScope();

当我添加更多控制器时,我将添加第一行的更多实例。我希望看到这个工作的方式是:

  • /foo/action收到了请求
    • Ninject将ISideBarFactory绑定到FooSideBarFactory并注入SideBarController
  • /bar/action收到了请求
    • Ninject将ISideBarFactory绑定到BarSideBarFactory并注入SideBarController
  • /baz/action收到了请求
    • 不存在BazSideBarFactory,因此Ninject将ISideBarFactory绑定到默认实现DefaultSideBarFactory,然后注入SideBarController

我已经在Contextual Binding咨询了Ninject维基页面,这似乎是我原本想要的 ,但我没有找到任何明显达到我目标的文件。

1 个答案:

答案 0 :(得分:3)

您可以将路线数据与Contextual-Binding

结合使用

<强>装订

// default binding - used if none of the conditions is met
kernel.Bind<IService>()
    .To<DefaultService>()

kernel.Bind<IService>()
    .To<BasicService>()
    .When(x=> IsRouteValueDefined("controller", "Service"));

kernel.Bind<IService>()
    .To<ExtraService>()
    .When(x=> IsRouteValueDefined("controller", "ExtraService"));

IsRouteValueDefined()方法

在定义路由键并指定routeValue等于路由键的路由值或null时返回true。

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().ToUpper() == routeValue.ToUpper();
}