首页 文章

MVC请求的Ninject上下文绑定

提问于
浏览
3

我有一个不寻常的情况将服务注入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 回答

  • 3

    您可以将路线数据与Contextual-Binding结合起来

    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() method

    定义路由键并指定 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();
    }
    

相关问题