Asp.net mvc 如何在Ninject中创建根据请求的控制器进行更改的绑定?
我有一个ASP.NET MVC 3应用程序,遇到了以下情况。在我的页面上,我有一个侧栏,它可以包含特定于该页面的相关链接,即,由控制器类型确定。链接将由当前页面的内容决定 我随后使用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
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