我正在用C#,.NET Framework 4.5.1開發ASP.NET Web Api 2.2。NinjectDependencyResolver失敗綁定ModelValidatorProvider
更新我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
,但它仍然不起作用。
有什麼想法?
UPDATE
調試我看到異常在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="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" />
第二次更新:
<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" />
以前的版本,這些組件是問題在於此類:
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;
}
而且我從ExceptionFilterAttribute
繼承的類使用WebContainerManager
:
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
我沒有得到循環。
你試過卸載所有的ninject軟件包並重新安裝它們嗎?確保你真的有最新版本? – BatteryBackupUnit 2014-10-17 09:16:34
是的,我這樣做,我得到了同樣的錯誤。 – VansFannel 2014-10-17 09:18:42
你可以上傳[mcve](http://stackoverflow.com/help/mcve)作爲視覺工作室項目在gist/github回購或類似的東西?我想刺穿它。 – BatteryBackupUnit 2014-11-10 07:18:25