Ninject在具有多个程序集的WebApi项目中抛出Activation Exception

我的asp.net WebApi项目包含多个服务,核心和数据访问程序集。 为了在项目中使用Ninject作为我的DI容器,我从NuGet添加了Ninject.Web.Common包。 然后,我实现了IDependencyResolver:

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver { readonly IKernel kernel; public NinjectDependencyResolver(IKernel kernel) : base(kernel) { this.kernel = kernel; } public IDependencyScope BeginScope() { return new NinjectDependencyScope(this.kernel.BeginBlock()); } } public class NinjectDependencyScope : IDependencyScope { IResolutionRoot resolver; public NinjectDependencyScope(IResolutionRoot resolver) { this.resolver = resolver; } public object GetService(System.Type serviceType) { if (resolver == null) throw new ObjectDisposedException("this", "This scope has been disposed"); var resolved = this.resolver.Get(serviceType); return resolved; } public System.Collections.Generic.IEnumerable GetServices(System.Type serviceType) { if (resolver == null) throw new ObjectDisposedException("this", "This scope has been disposed"); return this.resolver.GetAll(serviceType); } public void Dispose() { IDisposable disposable = resolver as IDisposable; if (disposable != null) disposable.Dispose(); resolver = null; } } 

这是我的Ninject.Web.Common.cs。

 public static class NinjectWebCommon { private static readonly Bootstrapper bootstrapper = new Bootstrapper(); ///  /// Starts the application ///  public static void Start() { DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); bootstrapper.Initialize(CreateKernel); } ///  /// Stops the application. ///  public static void Stop() { bootstrapper.ShutDown(); } ///  /// Creates the kernel that will manage your application. ///  /// The created kernel. private static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind().To(); RegisterServices(kernel); GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); return kernel; } ///  /// Load your modules or register your services here! ///  /// The kernel. private static void RegisterServices(IKernel kernel) { kernel.Bind(x => x.FromAssembliesInPath(AppDomain.CurrentDomain.RelativeSearchPath) .SelectAllIncludingAbstractClasses() .BindDefaultInterface() .Configure(config => config.InSingletonScope())); //kernel.Bind(x => // { // x.FromAssembliesMatching("*") // .SelectAllClasses() // .BindDefaultInterface() // .Configure(b => b.InTransientScope()); // }); //kernel.Load() //kernel.Bind().To(); //kernel.Bind(x => x // .FromAssembliesMatching("*") // .SelectAllClasses() // .BindDefaultInterface()); //.Configure(b => b.InTransientScope())); //kernel.Load("*.dll"); } } 

例外是

 [ActivationException: Error activating IHostBufferPolicySelector No matching bindings are available, and the type is not self-bindable. Activation path: 1) Request for IHostBufferPolicySelector 

我已经使用了各种注册(已注释掉)但没有工作。 命中NinjectWebCommon.cs – > CreateKernel()方法中的断点,GetService(System.Type serviceType)方法中的断点也是如此。 AppDomain.CurrentDomain.RelativeSearchPath解析为应用程序的bin目录,它包含所有dll,包括System.Web.Http.dll,其中包含IHostBufferPolicySelector类型。

如何正确使用Ninject.Extensions.Conventions来设置内核以进行类型解析?

从Remo的回答提示和Filip的评论以及大量的调试时间,我发现在GetService()实现中使用this.resolver.Get(serviceType)而不是this.resolver.TryGet(serviceType)是我情况的罪魁祸首。

我计划了一篇关于此的详细博客文章,但缺点是,一旦我们使用以下行将NinjectDependencyResolver插入MVC: GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); 我们没有定义框架级依赖项绑定(例如IHostBufferPolicySelector等),当一些框架级依赖项未通过Ninject解析时, Get()方法会引发exception。 使用TryGet()不会引发exception,并且框架会回退到未解析的(a.ka. null)依赖项(如IHostBufferPolicySelector)的默认依赖项。 所以,选项是

  1. 使用TryGet()方法解决依赖关系。
  2. Wrap Get in Try / Catch并丢弃该exception。

没有类HostBufferPolicySelector因此没有类, IHostBufferPolicySelector是默认接口。 您可以尝试BindAllInterfacesBindDefaultInterfaces