我正在使用C#,.NET Framework 4.5.1开发ASP.NET Web Api 2.2。
将我的Web.Api更新为Ninject 3.2.0后,我收到此错误:
Error activating ModelValidatorProvider using binding from ModelValidatorProvider to NinjectDefaultModelValidatorProvider
A cyclical dependency was detected between the constructors of two services.
Activation path:
3) Injection of dependency ModelValidatorProvider into parameter defaultModelValidatorProviders of constructor of type DefaultModelValidatorProviders
2) Injection of dependency DefaultModelValidatorProviders into parameter defaultModelValidatorProviders of constructor of type NinjectDefaultModelValidatorProvider
1) Request for ModelValidatorProvider
Suggestions:
1) Ensure that you have not declared a dependency for ModelValidatorProvider on any implementations of the service.
2) Consider combining the services into a single one to remove the cycle.
3) Use property injection instead of constructor injection, and implement IInitializable
if you need initialization logic to be run after property values have been injected.
我在NinjectWebCommon
中得到了例外:
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
var containerConfigurator = new NinjectConfigurator();
containerConfigurator.Configure(kernel);
}
}
NinjectDependencyResolver
上课:
using Ninject;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
namespace Matt.SocialNetwork.Web.Common
{
public class NinjectDependencyResolver : IDependencyResolver
{
private readonly IKernel _container;
public IKernel Container
{
get { return _container; }
}
public NinjectDependencyResolver(IKernel container)
{
_container = container;
}
public object GetService(Type serviceType)
{
return _container.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.GetAll(serviceType);
}
public IDependencyScope BeginScope()
{
return this;
}
public void Dispose()
{
// noop
}
}
}
NinjectConfigurator
上课:
public class NinjectConfigurator
{
public void Configure(IKernel container)
{
// Add all bindings/dependencies
AddBindings(container);
// Use the container and our NinjectDependencyResolver as
// application's resolver
var resolver = new NinjectDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
// Omitted for brevity.
}
奇怪的是它编译并且工作完美,但更新后它不起作用。
我已将此更改为public class NinjectDependencyResolver : IDependencyResolver, System.Web.Mvc.IDependencyResolver
,但仍无效。
有什么想法吗?
更新
调试我看到NinjectDependencyResolver
抛出了异常:
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.GetAll(serviceType);
}
它运行两次。首先serviceType
为IFilterProvider
,第二次serviceType
为ModelValidatorProvider
,之后我获得例外。
这些是我正在使用的Ninject包:
<package id="Ninject" version="3.2.2.0" targetFramework="net451" />
<package id="Ninject.MVC5" version="3.2.1.0" targetFramework="net45" />
<package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net451" />
<package id="Ninject.Web.Common.WebHost" version="3.2.3.0" targetFramework="net451" />
<package id="Ninject.Web.WebApi" version="3.2.2.0" targetFramework="net451" />
这些程序集的先前版本是:
<package id="Ninject" version="3.2.2.0" targetFramework="net45" />
<package id="Ninject.MVC5" version="3.2.1.0" targetFramework="net45" />
<package id="Ninject.Web.Common" version="3.2.2.0" targetFramework="net451" />
<package id="Ninject.Web.Common.WebHost" version="3.2.0.0" targetFramework="net45" />
<package id="Ninject.Web.WebApi" version="3.2.0.0" targetFramework="net451" />
第二次更新
我发现问题出现在这个课程中:
public static class WebContainerManager
{
public static IKernel GetContainer()
{
var resolver = GlobalConfiguration.Configuration.DependencyResolver as NinjectDependencyResolver;
if (resolver != null)
{
return resolver.Container;
}
throw new InvalidOperationException("NinjectDependencyResolver not being used as the MVC dependency resolver");
}
public static T Get<T>()
{
return GetContainer().Get<T>();
}
}
我在这里设置Dependency Resolver
:
public class NinjectConfigurator
{
/// <summary>
/// Entry method used by caller to configure the given
/// container with all of this application's
/// dependencies. Also configures the container as this
/// application's dependency resolver.
/// </summary>
public void Configure(IKernel container)
{
// Add all bindings/dependencies
AddBindings(container);
// Use the container and our NinjectDependencyResolver as
// application's resolver
var resolver = new NinjectDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
我在继承自WebContainerManager
:
ExceptionFilterAttribute
public class UnhandledExceptionFilter : ExceptionFilterAttribute
{
private readonly IExceptionLogHelper excepLogHelper;
public UnhandledExceptionFilter()
: this(WebContainerManager.Get<IExceptionLogHelper>()) {}
public UnhandledExceptionFilter(IExceptionLogHelper exceptionLogHelper)
{
this.excepLogHelper = exceptionLogHelper;
}
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
this.excepLogHelper.LogException(actionExecutedContext);
}
}
所以,如果我删除WebContainerManager
,我就没有那个循环。
答案 0 :(得分:13)
在升级Ninject软件包(甚至卸载和删除旧软件包)后,我对WebApi2和Ninject初始化产生了各种各样的悲痛。
特别是在你的情况下,我会删除这些代码行:
// Use the container and our NinjectDependencyResolver as
// application's resolver
var resolver = new NinjectDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
因为它们可能是错误的原因(NinjectWebCommon.cs和Ninject库现在处理初始化依赖项解析器)。
对于那些跟随类似升级途径的人。对我有用的是:
删除旧的DependencyResolver初始化代码(对我而言,这导致您在Ninject / WebApi2的早期版本中提到的特定错误,将这些行放在WebApiConfig.cs Register()方法中就是如何初始化DependencyResolver ......这不再是这种情况):
var kernel = new StandardKernel();
config.DependencyResolver = new NinjectDependencyResolver(kernel);
安装Ninject.Web.WebApi.WebHost包。这个安装了 NinjectWebCommon.cs文件。对我来说,只有Ninject.Web.WebApi和它 依赖项没有创建此文件。
我已安装并正在使用的Ninject包供参考:
<package id="Ninject" version="3.2.2.0" targetFramework="net452" />
<package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net452" />
<package id="Ninject.Web.Common.WebHost" version="3.2.0.0" targetFramework="net452" />
<package id="Ninject.Web.WebApi" version="3.2.3.0" targetFramework="net452" />
<package id="Ninject.Web.WebApi.WebHost" version="3.2.3.0" targetFramework="net452" />
答案 1 :(得分:6)
请确保您的bin文件夹中没有任何旧的Ninject
或Ninject.Web.Common.*
dll。
在我从Nuget卸载Ninject.Web.Common
,Ninject.Web.Common.WebHost
,Ninject.Web.WebApi
和Ninject.MVC5
并按顺序安装WebApiContrib.IoC.Ninject
后,我的解决方案出现了同样的问题在示例中使用GlobalConfiguration.Configuration.DependencyResolver
。我保留了我已安装的Ninject
版本(确实是3.2.2)。
我第一次进行更改时没有出现错误。然而,在从几个git分支移动到我当前的工作后,我看到了错误。上周运行良好的代码现在抛出了同样的错误。
我的bin文件夹似乎引用了我删除的旧Ninject.*
个包。删除这些文件后,我的项目按预期工作。
答案 2 :(得分:2)
The cyclic dependency is between the classes "NinjectDefaultModelValidatorProvider" and "DefaultModelValidatorProviders".Simply add a binding for "DefaultModelValidatorProviders" on your startup like below:
_kernel.Bind<DefaultModelValidatorProviders>().ToConstant(new DefaultModelValidatorProviders(config.Services.GetServices(typeof (ModelValidatorProvider)).Cast<ModelValidatorProvider>()));
答案 3 :(得分:1)
在我的情况下,它在Owin Selfhost上下文中工作正常,但在IIS中托管时却没有。我的解决方案是从nuget包中删除除Ninject本身之外的所有Ninject相关程序集。
然后我编写了自己的DependencyResolver类,随时在评论中留下改进。
public class NinjectDepsolver : IDependencyResolver
{
private IKernel _kernel;
public NinjectDepsolver(IKernel kernel)
{
_kernel = kernel;
}
public void Dispose()
{
_kernel = null;
}
public object GetService(Type serviceType) => _kernel.TryGet(serviceType);
public IEnumerable<object> GetServices(Type serviceType) => _kernel.GetAll(serviceType).ToArray();
public IDependencyScope BeginScope() => new DepScope(this);
class DepScope : IDependencyScope
{
private NinjectDepsolver _depsolver;
public DepScope(NinjectDepsolver depsolver)
{
_depsolver = depsolver;
}
public void Dispose()
{
_depsolver = null;
}
public object GetService(Type serviceType) => _depsolver.GetService(serviceType);
public IEnumerable<object> GetServices(Type serviceType) => _depsolver.GetServices(serviceType);
}
}
然后在你的Owin配置方法中:
var kernel = new StandardKernel();
kernel.Load(<your module classes>);
var httpConfig = new HttpConfiguration();
var httpConfig.DependencyResolver = new NinjectDepsolver(kernel);
var httpConfig.MapHttpAttributeRoutes();
app.UseWebApi(httpConfig);
答案 4 :(得分:1)
这对我有用。
uninstall-package Ninject.Web.WebApi.WebHost
上面的命令卸载了版本&#39; Ninject.Web.WebApi.WebHost 3.2.4.0&#39;并且错误消失!!
请再次确认,我已使用命令
安装了相同的软件包 install-package Ninject.Web.WebApi.WebHost
并且命令安装了软件包&#39; Ninject.Web.WebApi.WebHost 3.2.4.0&#39;并且错误再次出现。
答案 5 :(得分:0)
int main(void) {
int x;
do {
printf("Height: ");
} while(!((scanf("%d", &x)) == 0) && !(x > 0 && x < 23));
}
这也有效。
答案 6 :(得分:0)
我通过在Global.asax
(初始化我的StandardKernel
的位置)中添加以下行来解决此问题:
kernel.Bind<DefaultModelValidatorProviders>().ToConstant(new DefaultModelValidatorProviders(GlobalConfiguration.Configuration.Services.GetModelValidatorProviders()));
答案 7 :(得分:0)
我在OWIN中为此苦苦挣扎了一段时间,并且总是最终恢复到以前的版本。但是没有什么比检查他们的github上的示例应用程序更重要了。
首先请确保您摆脱了可能要添加到配置中的任何手动Dependency Resolver,然后在启动过程中只需执行以下操作:
appBuilder.UseNinjectMiddleware(() => yourKernel); // or a function that returns your kernel
appBuilder.UseNinjectWebApi(yourHttConfiguration);
应该可以。
答案 8 :(得分:-2)
我卸载了Ninject.Web.WebApi.WebHost软件包,并且不再存在错误或发生错误。
答案 9 :(得分:-2)
我遇到了同样的错误,并卸载了Ninject.Web.WebApi.WebHost软件包并删除了错误。