1

我有点进退两难,老实说,这是一个边缘案例,但仍然存在问题。

目前我正在使用 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 知道类型和命名空间,但在创建控制器的上下文中,它不知道命名空间只是控制器名称,所以我这样做是为了满足插件的隔离,以及动态控制器的位置,这是一种迂回的做法,但这是人们在 AutoFac 之前用 AutoFac 做过的类似事情的例子

4

1 回答 1

3

在我看来,绑定应该在应用程序启动时创建一次,并且在第一次解析后不再更改。其他一切都可能导致奇怪的问题。除非您为每个插件使用 AppDomain 进行适当的隔离,否则无论如何您都无法真正卸载它们。您可以使它们成为有条件的并使用某些配置禁用它们,而不是卸载绑定。

如果您真的想卸载绑定,那么我建议不要为单个绑定执行此操作,而是利用模块。将属于一个插件的所有绑定一起加载到一个或多个模块中,然后卸载这些模块而不是单个绑定。

于 2011-12-07T18:26:03.040 回答