在MVC请求上Ninject上下文绑定 [英] Ninject Contextual Binding on MVC Request

查看:91
本文介绍了在MVC请求上Ninject上下文绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将服务注入ASP.NET MVC控制器中时,我遇到一种不寻常的情况. Controller提供了一个在页面上呈现侧栏菜单的动作,注入Controller的服务是创建侧栏内容的工厂.该动作用[ChildActionOnly]属性修饰:仅在渲染另一个动作时才可以渲染侧栏.

I have an unusual situation injecting a service into an ASP.NET MVC Controller. The Controller provides a single action to render a side-bar menu on the page, and the service injected into the Controller is a factory to create the side-bar content. The action is decorated with the [ChildActionOnly] attribute: the side bar can only be rendered when rendering another action.

困难在于,我想根据请求的页面(=控制器)注入侧栏工厂抽象的不同实例.以前,我是使用某种抽象工厂来进行此操作的,该工厂的实现很笨拙,它使用控制器名称字符串来确定要使用的具体工厂实现;我现在将其移至适当的抽象工厂,因此需要将对工厂类型的选择移至其他位置.

The difficulty comes in that I want to inject different instances of the side-bar factory abstraction according to the page (= Controller) being requested. Previously, I was doing this using a sort-of abstract factory, which had the inelegant implementation of using the controller name string to determine which concrete factory implementation to use; I've now moved this to a proper abstract factory, and thus need to move the selection of the factory type elsewhere.

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

My Ninject bindings are currently defined very simply as:

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

随着我添加更多控制器,我将添加第一行的更多实例.我希望看到此工作的方式是:

and as I add more controllers, I will add more instances of the first line. The way I would like to see this working is:

    收到
  • /foo/action请求
    • Ninject将ISideBarFactory绑定到FooSideBarFactory并注入到SideBarController
    • /foo/action request received
      • Ninject binds ISideBarFactory to FooSideBarFactory and injects into SideBarController
      • Ninject将ISideBarFactory绑定到BarSideBarFactory并注入到SideBarController
      • Ninject binds ISideBarFactory to BarSideBarFactory and injects into SideBarController
      • 不存在BazSideBarFactory,因此Ninject将ISideBarFactory绑定到默认实现DefaultSideBarFactory,并注入到SideBarController
      • No BazSideBarFactory exists, so Ninject binds ISideBarFactory to the default implementation, DefaultSideBarFactory, and injects into SideBarController

      我已经查阅了 Contextual Binding 上的Ninject Wiki页面,成为我想要的原则上,但是我还没有找到任何明显可以实现我目标的文件.

      I've consulted the Ninject wiki page on Contextual Binding, which appears to be what I want in principle, but I haven't found anything documented there which obviously achieves my goal.

      推荐答案

      您可以结合使用上下文绑定

      绑定

      // 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()方法

      IsRouteValueDefined() method

      当定义了路由密钥并指定了routeValue等于路由密钥的路由值或为null时,返回true.

      Returns true when route key is defined and specified routeValue equals route value for route key or is null.

      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();
      }
      

      这篇关于在MVC请求上Ninject上下文绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆