2

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

我已经关注了Phil Haack 的关于使用和单独的控制器渲染动态侧边栏的博客文章。Html.Action我喜欢这种方法给我的关注点分离:我的控制器对侧边栏一无所知,这是应该的方式。

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

kernel.Bind<SideBar>().ToMethod(_ => controllerName == "foo" 
                                         ? new FooSideBar(kernel.Get<UrlHelper>()) 
                                         : new BarSideBar(kernel.Get<UrlHelper>()));

但是这段代码有很多错误,尤其是我无法在 lambda 中获取控制器名称这一事实,以及当第三种类型的控制器出现时会发生什么的问题,然后第四等

请注意,我不能使用WhenInjectedInto<T>(),因为SideBar实例将始终注入到SideBarController.

值得一提的SideBar是,当前正在通过 Ninject Factory 扩展创建 的实例,因此相关的侧边栏绑定如下(我硬绑定了 SideBar 的实现,只是为了证明该方法到目前为止有效):

kernel.Bind<ISideBarFactory>().ToFactory().InRequestScope();
kernel.Bind<SideBar>().To<FooSideBar>().InRequestScope();

SideBar最后,我基本上在派生类型和控制器类型之间建立了一对一的映射关系。感觉这里可能有点重复,但也代表了组件之间的关系,所以我觉得我可以接受。

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

4

3 回答 3

3

我会尝试回答,但我现在不在电脑附近,所以会有点模糊。

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

于 2012-07-23T20:33:04.700 回答
1

我不确定这是否可以使用 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 工作。

请阅读:http ://blog.voltje.be/2012/08/22/creating-a-dynamic-sidebar-with-asp-net-mvc-ninject/

于 2012-07-23T19:53:13.680 回答
0

建议:

  • 不要注入侧边栏。
  • 而是注入 [sidebar]ContentProvider。
  • 在全局 asax 中绑定一个默认实现(每个请求),然后在控制器中根据需要取消绑定并重新绑定。
于 2012-07-23T19:26:32.387 回答