Den*_*nko 30 asp.net-mvc ninject
最近我切换到Ninject 2.0版本并开始收到以下错误:
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.
但是,我无法找到某种复制路径.有时它会发生,有时它不会发生.我正在使用NinjectHttpApplication自动控制器注入.控制器在单独的程序集中定义:
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();
}
/* ............. */
}
Run Code Online (Sandbox Code Playgroud)
也许有人熟悉这个错误.
有什么建议?
小智 23
我终于最近想出了这个问题.显然,NinjectHttpApplication.RegisterAllControllersIn()函数不会执行所需的所有正确绑定.它将您的具体控制器实现绑定到IController请求.例如,如果您有一个名为SampleMvcController的控制器类,它继承自System.Web.Mvc.Controller.它将在应用程序启动期间执行以下命名绑定:
kernel.Bind<IController>().To(SampleMvcController).InTransientScope().Named("SampleMvc");
Run Code Online (Sandbox Code Playgroud)
但调试NinjectControllerFactory的时候,我发现,要求正在作出的Ninject内核返回一个对象类"SampleMvcController",而不是一个具体实现一个IController,采用了名为"SampleMvc"的结合.
因此,当涉及SampleMvcController的第一个Web请求生成时,它会创建SampleMvcController与其自身的绑定.但这不是线程安全的.因此,如果您同时发出多个Web请求,则绑定可能会多次发生,现在您因为SampleMvcController具有多个绑定而留下此错误.
您可以在使Web应用程序重新启动后立即通过快速刷新MVC URL来验证这一点.
修复:
解决此问题的最简单方法是为控制器绑定创建新的NinjectModule,并在应用程序启动期间加载此模块.在此模块中,您将自动绑定每个已定义的控制器,如下所示:
class ControllerModule : StandardModule {
public override Load() {
Bind<SampleMvcController>().ToSelf();
Bind<AnotherMvcController>().ToSelf();
}
}
Run Code Online (Sandbox Code Playgroud)
但是如果您不介意更改Ninject源代码,可以修改RegisterAllControllersIn()函数以自动绑定它遇到的每个控制器.
Ste*_*ook 16
几个月来我一直在处理这个问题.我尝试了很多选择,但无法找到解决方案.我知道这是一个线程问题,因为只有当我的网站负载很重时才会发生.最近,在ninject源代码中报告并修复了一个错误,解决了这个问题.
以下是对该问题的参考.它在Ninject源的2.1.0.70版中得到修复.通过删除行,关键更改在KernelBase.cs中
context.Plan = planner.GetPlan(service);
Run Code Online (Sandbox Code Playgroud)
并替换它
lock (planner)
{
context.Plan = planner.GetPlan(service);
}
Run Code Online (Sandbox Code Playgroud)
要在MVC中使用这个新版本,您需要获取Ninject的最新版本,然后获取ninject.web.mvc的最新版本.使用新的Ninject构建构建ninject.web.mvc.
我已经使用这个新版本大约一个星期,负载很重,没有问题.它是最长的没有问题所以我认为这是一个解决方案.
| 归档时间: |
|
| 查看次数: |
12284 次 |
| 最近记录: |