Asp.net mvc 如何在Ninject中创建根据请求的控制器进行更改的绑定?

Asp.net mvc 如何在Ninject中创建根据请求的控制器进行更改的绑定?,asp.net-mvc,dependency-injection,ninject,asp.net-mvc-4,Asp.net Mvc,Dependency Injection,Ninject,Asp.net Mvc 4,我有一个ASP.NET MVC 3应用程序,遇到了以下情况。在我的页面上,我有一个侧栏,它可以包含特定于该页面的相关链接,即,由控制器类型确定。链接将由当前页面的内容决定 我随后使用Html.Action和一个单独的控制器呈现了这样的动态侧栏。我喜欢这种方法给我的关注点分离:我的控制器对侧栏一无所知,这是应该的 现在,我想将一个派生类型的侧栏的实例注入我的侧栏控制器,调用该操作以呈现侧栏本身。每个控制器都有一种派生的侧栏,因此我发现自己想要编写类似的代码: kernel.Bind<Side

我有一个ASP.NET MVC 3应用程序,遇到了以下情况。在我的页面上,我有一个侧栏,它可以包含特定于该页面的相关链接,即,由控制器类型确定。链接将由当前页面的内容决定

我随后使用
Html.Action
和一个单独的控制器呈现了这样的动态侧栏。我喜欢这种方法给我的关注点分离:我的控制器对侧栏一无所知,这是应该的

现在,我想将一个派生类型的
侧栏
的实例注入我的
侧栏控制器
,调用该操作以呈现侧栏本身。每个控制器都有一种派生的
侧栏
,因此我发现自己想要编写类似的代码:

kernel.Bind<SideBar>().ToMethod(_ => controllerName == "foo" 
                                         ? new FooSideBar(kernel.Get<UrlHelper>()) 
                                         : new BarSideBar(kernel.Get<UrlHelper>()));
最后,我基本上在
侧栏的派生类型和控制器类型之间有一对一的映射。这感觉有点像这里可能有点重复,但它也代表了组件之间的关系,所以我认为我可以接受

这一切都让我觉得我对这部分问题的处理方法是错误的,因此我欢迎关于如何使用Ninject实现干净解决方案的建议

建议:

  • 不要插入侧边栏
  • 而是注入[sidebar]ContentProvider
  • 在全局asax中绑定默认实现(每个请求),然后在控制器中根据需要取消绑定和重新绑定
建议:

  • 不要插入侧边栏
  • 而是注入[sidebar]ContentProvider
  • 在全局asax中绑定默认实现(每个请求),然后在控制器中根据需要取消绑定和重新绑定
我不确定使用ninject是否可行,但它使用的是ModelBinding,如下所示:

public interface ISidebar
    {
    }
    public class Sidebar1 : ISidebar
    {
    }
    public class Sidebar2 : ISidebar
    {
    }


 public class SidebarModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var controller = controllerContext.RouteData.Values["Controller"];
            var action = controllerContext.RouteData.Values["Action"];

            switch (controller.ToString())
            {
                case "Home":
                    return new Sidebar1();

                default:
                    return new Sidebar2();

            }

            throw new NotImplementedException();
        }
    }


 public class TestController : Controller
    {
        public TestController()
        {
        }

        public string Index(ISidebar sidebar)
        {
            //Do something with it
            return "OK";
        }
    }

//Add to the Application_Start
ModelBinders.Binders.Add(typeof(ISidebar), new SidebarModelBinder());
编辑:花了我一段时间,但还是设法用Ninject让它工作起来


请阅读:

我不确定使用ninject是否可行,但它使用的是ModelBinding,如下所示:

public interface ISidebar
    {
    }
    public class Sidebar1 : ISidebar
    {
    }
    public class Sidebar2 : ISidebar
    {
    }


 public class SidebarModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var controller = controllerContext.RouteData.Values["Controller"];
            var action = controllerContext.RouteData.Values["Action"];

            switch (controller.ToString())
            {
                case "Home":
                    return new Sidebar1();

                default:
                    return new Sidebar2();

            }

            throw new NotImplementedException();
        }
    }


 public class TestController : Controller
    {
        public TestController()
        {
        }

        public string Index(ISidebar sidebar)
        {
            //Do something with it
            return "OK";
        }
    }

//Add to the Application_Start
ModelBinders.Binders.Add(typeof(ISidebar), new SidebarModelBinder());
编辑:花了我一段时间,但还是设法用Ninject让它工作起来


请在以下网址阅读:

我会尝试回答,但我现在不在电脑旁,所以有点含糊不清


基本上,您可以将另一个参数传递给Html.Action,因此如果该参数是请求或从请求中收集到的内容(例如控制器名称或Url部分),那么您可以使用该参数来确定要显示的侧栏。您可能需要将工厂注入到侧栏控制器中,并使用它来创建正确的控制器,或者进行其他操作,但是一旦您知道需要哪个侧栏,就变得容易多了

我可以试着回答,但我现在不在电脑旁,所以有点含糊不清


基本上,您可以将另一个参数传递给Html.Action,因此如果该参数是请求或从请求中收集到的内容(例如控制器名称或Url部分),那么您可以使用该参数来确定要显示的侧栏。您可能需要将工厂注入到侧栏控制器中,并使用它来创建正确的控制器,或者进行其他操作,但是一旦您知道需要哪个侧栏,就变得容易多了

我看不出用XML指定绑定有助于解决我描述的问题。你是100%正确的。对不起,我完全误解了这个问题。我想在匆忙中,我实际上读了我想读的东西,而不是实际写的东西。我正在删除注释,以便将来不会误导任何人。我不认为用XML指定绑定将有助于解决我描述的问题。你是100%正确的。对不起,我完全误解了这个问题。我想在匆忙中,我实际上读了我想读的东西,而不是实际写的东西。我正在删除评论,以免将来误导任何人。谢谢Rory。我不想让我的个人控制器知道侧栏,这感觉像是违反了SRP。我绝对不希望我的控制器摆弄DI绑定;我更喜欢遵循这个模式。谢谢Rory。我不想让我的个人控制器知道侧栏,这感觉像是违反了SRP。我绝对不希望我的控制器摆弄DI绑定;我更喜欢遵循这种模式。这是一个很好的实现,使用MVC本身。不幸的是,在我的实现中,我发现ModelBinder仅在呈现侧栏时才被调用,这意味着
控制器
变量是“侧栏”,而
操作
变量是“显示”。这一定是因为我使用的是
Html.action()
如上所述。聊天后,您确实在做一些不同的事情。我的方法很好用,只是不像你想达到的那样。正如推特上所说,我认为你应该调整你的逻辑,以实现你想要的……顺便说一句,我把这作为一个答案,因为它可能会解决一些人的问题。最后,在action方法中使用一个额外的参数似乎更好:public ActionResult Display(边栏边栏,string somevaluetoindicatedwhichsidebartorender)。这似乎是TS的解决方案!用Ninject解决方案的链接更新了我的答案!:)这是一个很好的实现,使用MVC本身。不幸的是,在我的实现中,我发现ModelBinder仅在呈现侧栏时才被调用,这意味着
控制器
变量是“侧栏”,而
操作
变量是“显示”。这一定是因为我使用的是
Html.action()
如上所述。聊天后,您确实在做一些不同的事情。我的方法很好用,只是不像你想达到的那样。正如在推特上所说的,我认为你应该调整你的逻辑,以实现你想要的……我让t