MVC请求上的Ninject上下文绑定
本文关键字:上下文 绑定 Ninject 请求 MVC | 更新日期: 2023-09-27 17:58:40
我在将服务注入ASP.NET MVC控制器时遇到了异常情况。控制器提供了一个在页面上呈现侧栏菜单的单一操作,注入控制器的服务是创建侧栏内容的工厂。该动作使用[ChildActionOnly]
属性进行装饰:只有在渲染另一个动作时才能渲染侧栏。
困难在于,我想根据请求的页面(=控制器)注入侧栏工厂抽象的不同实例。以前,我使用一种抽象工厂来完成这项工作,它有一个不雅的实现,即使用控制器名称字符串来确定要使用哪个具体的工厂实现;我现在已经将其转移到一个适当的抽象工厂,因此需要将工厂类型的选择转移到其他地方。
我的Ninject绑定目前定义得非常简单:
Kernel.Bind<ISideBarFactory>().To<FooSideBarFactory>().InRequestScope();
Kernel.Bind<ISideBarFactory>().To<DefaultSideBarFactory>().InRequestScope();
随着我添加更多的控制器,我将添加第一行的更多实例。我希望看到这种工作方式是:
- 收到
/foo/action
请求- Ninject将
ISideBarFactory
与FooSideBarFactory
结合并注入SideBarController
- Ninject将
- 收到
/bar/action
请求- Ninject将
ISideBarFactory
与BarSideBarFactory
结合并注入SideBarController
- Ninject将
- 收到
/baz/action
请求- 不存在
BazSideBarFactory
,因此Ninject将ISideBarFactory
绑定到默认实现DefaultSideBarFactory
,并注入到SideBarController
中
- 不存在
我查阅了关于上下文绑定的Ninject wiki页面,这似乎是我原则上想要的,但我没有发现任何明显达到我目标的文档。
您可以将读取路由数据与上下文绑定相结合
绑定
// 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();
}