我有点两难,说实话是一个边缘案例,但仍然存在问题。
目前我正在使用Ninject MVC并绑定所有我的控制器,如下所示:
Kernel.Bind<SomeController>.ToSelf();
对于我需要做的99%的事情,这是有用的,但是目前我正在做一些关于动态路由和动态控制器的古怪的东西,这需要我手动编写一个方法来获得控制器的类型来自ninject。现在我最初认为这很容易,但它不是......我期待我可以根据它的名字得到控制器,但那不起作用。
Kernel.Get<IController>("SomeController");
这让我想到它可能是因为它只知道对SomeController的绑定,而不是IController。所以我想,我可以像我这样编写所有绑定:
Kernel.Bind<IController>.To<SomeController>().Named("SomeController");
这样就可以很容易地从执行前面代码的名称中获取控制器的类型,但是如果我以这种方式绑定,那么当我解除绑定控制器时我会遇到问题(因为插件可以是在运行时加载和卸载)。正常:
Kernel.Unbind<SomeController>()
哪个很棒,将不再有效,我将不得不这样做:
Kernel.Unbind<IController>();
然而,我意识到我需要给它一些约束来告诉它我想要取消绑定的这种类型的绑定,并且似乎没有可用的重载或DSL ...
所以我被困在摇滚和硬地之间,因为我需要满足ControllerLookup方法,但也需要保留它以便我可以在运行时轻松添加和删除绑定。
protected override Type GetControllerType(RequestContext requestContext, string controllerName) {
//... find and return type from ninject
}
有人有什么想法吗?
(只是问任何人问我为什么这样做,因为我加载插件的方式,Ninject知道类型和命名空间,但在创建控制器的上下文中它不知道命名空间只是控制器名称,所以我这样做是为了满足插件的隔离,以及动态控制器的位置,这是一种迂回的方式,但它是人们在Example of similar thing with AutoFac之前用AutoFac做的事情)
答案 0 :(得分:3)
在我看来,绑定应该在应用程序启动时创建一次,并且在第一次解析后不再更改。其他一切都可能导致奇怪的问题。除非你为每个插件使用AppDomain进行适当的隔离,否则无论如何都无法真正卸载它们。您可以使用条件并使用某些配置禁用它们,而不是卸载绑定。
如果你真的想卸载绑定,那么我建议不要单独绑定,而是利用模块。将属于一个插件的所有绑定一起加载到一个或多个模块中,然后卸载这些模块而不是单个绑定。