问题描述
最近,我切换到Ninject 2.0版本,并开始收到以下错误:
发生错误:错误激活SomeController
多个匹配的绑定可用。
激活路径:
1)请给SomeController建议:
1)确保您已经定义了SomeController绑定只有一次。
不过,我无法找到特定的再现路径。有时它发生时,有时它没有。
我使用 NinjectHttpApplication
自动控制器注入。控制器在单独的程序定义的:
公共类应用:NinjectHttpApplication
{
保护覆盖的iKernel CreateKernel()
{
INinjectModule [] =模块新INinjectModule [] {
新MiscModule(),
新ProvidersModule(),
新RepositoryModule(),
新ServiceModule()
}; 返回新StandardKernel(模块);
} 保护覆盖无效OnApplicationStarted()
{
的RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(Sample.Mvc);
base.OnApplicationStarted();
} / * * ............. /}
也许有人熟悉这个错误。
任何意见?
我终于想通最近这个问题了。显然,NinjectHttpApplication.RegisterAllControllersIn()函数没有做所有需要的正确的绑定。它结合您的具体控制器实现,以一个IController请求。例如,如果你有一个名为SampleMvcController控制器类,它继承System.Web.Mvc.Controller。它会做下面的命名在应用程序启动绑定:
<$p$p><$c$c>kernel.Bind<IController>().To(SampleMvcController).InTransientScope().Named(\"SampleMvc\");但调试NinjectControllerFactory的时候,我发现,要求对Ninject内核正在作出返回一个对象类SampleMvcController,而不是一个具体实现一个IController,采用的SampleMvc命名的结合。
由于这个原因,即涉及SampleMvcController第一web请求时,它创建一个结合SampleMvcController的本身。这不是线程安全的,但。所以,如果你有多个Web请求一次正在进行,绑定可以发生不止一次了,现在你只剩下这个错误具有针对SampleMvcController多个绑定。
您可以通过快速刷新一个MVC的URL,从而导致Web应用程序重新启动后立即验证这一点。
解决方法:
要解决这个问题,最简单的方法是创建一个新的NinjectModule为控制器绑定,并在应用程序启动加载这个模块。在这个模块中,你的自我约束每个定义的控制器,就像这样:
类ControllerModule:StandardModule {
公众覆盖负载(){
绑定&LT; SampleMvcController&GT;()ToSelf()。
绑定&LT; AnotherMvcController&GT;()ToSelf()。
}
}
但是,如果你不介意改变Ninject源$ C $ C,可以修改RegisterAllControllersIn()函数的自每个控制器绑定遇到。
Recently I've switched to Ninject 2.0 release and started getting the following error:
Error occured: Error activating SomeController More than one matching bindings are available. Activation path: 1) Request for SomeController Suggestions: 1) Ensure that you have defined a binding for SomeController only once.
However, I'm unable to find certain reproduction path. Sometimes it occurs, sometimes it does not.I'm using NinjectHttpApplication
for automatic controllers injection. Controllers are defined in separate assembly:
public class App : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
INinjectModule[] modules = new INinjectModule[] {
new MiscModule(),
new ProvidersModule(),
new RepositoryModule(),
new ServiceModule()
};
return new StandardKernel(modules);
}
protected override void OnApplicationStarted()
{
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn("Sample.Mvc");
base.OnApplicationStarted();
}
/* ............. */
}
Maybe someone is familiar with this error.
Any advice?
I finally figured this issue out recently. Apparently, the NinjectHttpApplication.RegisterAllControllersIn() function doesn't do all of the proper bindings needed. It binds your concrete controller implementations to IController requests. For example, if you have a controller class called SampleMvcController, which inherits from System.Web.Mvc.Controller. It would do the following named binding during application start:
kernel.Bind<IController>().To(SampleMvcController).InTransientScope().Named("SampleMvc");
But when debugging the NinjectControllerFactory, I find that request are being made for the Ninject Kernel to return an object for the class "SampleMvcController", not for a concrete implementation of IController, using the named binding of "SampleMvc".
Because of this, when the first web request that involves the SampleMvcController is made, it creates a binding of SampleMvcController to itself. This is not thread safe though. So if you have several web requests being made at once, the bindings can potentially happen more than once, and now you are left with this error for having multiple bindings for the SampleMvcController.
You can verify this by quickly refreshing an MVC URL, right after causing your web application to restart.
The fix:
The simplest way to fix this issue is to create a new NinjectModule for your controller bindings, and to load this module during application start. Within this module, you self bind each of your defined controllers, like so:
class ControllerModule : StandardModule {
public override Load() {
Bind<SampleMvcController>().ToSelf();
Bind<AnotherMvcController>().ToSelf();
}
}
But if you don't mind changing the Ninject source code, you can modify the RegisterAllControllersIn() function to self bind each controller it comes across.
这篇关于错误&QUOT;超过一个匹配绑定可用&QUOT;使用Ninject.Web.Mvc 2.0和ASP.NET MVC 1.0时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!