在MVC请求上Ninject上下文绑定 [英] Ninject Contextual Binding on MVC Request
问题描述
在将服务注入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
toFooSideBarFactory
and injects intoSideBarController
- Ninject将
ISideBarFactory
绑定到BarSideBarFactory
并注入到SideBarController
- Ninject binds
ISideBarFactory
toBarSideBarFactory
and injects intoSideBarController
- 不存在
BazSideBarFactory
,因此Ninject将ISideBarFactory
绑定到默认实现DefaultSideBarFactory
,并注入到SideBarController
- No
BazSideBarFactory
exists, so Ninject bindsISideBarFactory
to the default implementation,DefaultSideBarFactory
, and injects intoSideBarController
我已经查阅了 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 isnull
.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屋!
- Ninject binds
- Ninject将