处置IActivationBlock并导入IKernel时出错

时间:2012-06-26 20:25:47

标签: ninject asp.net-mvc-4 asp.net-web-api

当我尝试使用下面的解决方案将Ninject 3与MVC 4 RC Web Api项目一起使用时,问题就出现了:

http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/

此解决方案使用IActivationBlock(使用IKernel中的BeginBlock方法创建)来实现调用范围。使用常规Ninject项目,似乎工作正常,但是当项目使用扩展名Ninject.Extensions.Interception.DynamicProxy时,调用激活块的Dispose方法时会发生以下异常:

  

加载Ninject组件IAdviceRegistry

时出错      

内核的组件容器中没有注册此类组件。

并且,在下一次创建新的ActivationBlock并调用Resolve方法时,会发生以下异常:

  

加载Ninject组件ICache时出错

     

内核的组件容器中没有注册此类组件。

似乎问题与MVC更新没有直接关系,但是DynamicProxy和IActivationBlock之间存在一些不兼容。

编辑:

问题的根源是当其中一个类型在构造函数上需要IKernel时,它与DynamicProxy没有直接关系,但只有在引用此程序集时才会出现第一个异常。

因此,如果您的类型需要IKernel,则总会出现第二个错误(与ICache相关)。

1 个答案:

答案 0 :(得分:0)

总结你的好分析:你在ActivationBlock中创建一个类的实例,它直接依赖于IKernel。

这是一个逻辑缺陷,因为ActivationBlock的想法是恢复状态"在处理块之后的内核以及可以访问内核并且可以不可逆地改变任何绑定的实例。 (是的,实例可能是一个IDisposable,它可以自我清理;然后没有逻辑缺陷 - 只是一个不寻常的用例)。

我的经验是,绝大多数这些用途是调用IKernel.Get< ...>(...)和朋友。显然,这在ActivationBlock中是有效的:您只是请求超过您需要的内容:IKernel而不是IResolutionRoot(例如,您不需要IKernel的IBindingRoot)。更改班级中的类型,你会没事的。

P.S。感谢您对异常来源的分析。它帮助我解决了自己的问题。