Ninject抛出激活异常与多种组件的项目的WebAPI [英] Ninject throws Activation Exception in a WebApi project with multiple assemblies

查看:212
本文介绍了Ninject抛出激活异常与多种组件的项目的WebAPI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My asp.net WebApi project comprises of multiple assemblies for Services, Core and Data Access. In an attempt to use Ninject as my DI container in the project, I added Ninject.Web.Common package from NuGet. Then, I Implemented IDependencyResolver as:

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<object> 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。

Here is my Ninject.Web.Common.cs.

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();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
        RegisterServices(kernel);

        GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
        return kernel;
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    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<ISecurityService>().To<SecurityServiceImplementation>();

        //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类型。

I have used various registrations (commented out) but none work. The break point in NinjectWebCommon.cs -> CreateKernel() method is hit and so does the break point in GetService(System.Type serviceType) method. AppDomain.CurrentDomain.RelativeSearchPath resolves to the bin directory of the app and it contains all the dlls including System.Web.Http.dll which contains the IHostBufferPolicySelector type.

我如何正确使用Ninject.Extensions.Conventions设置类型分辨率的内核?

How can I properly use the Ninject.Extensions.Conventions to setup the kernel for type resolution?

推荐答案

从提示,我发现使用的this.resolver.Get(的serviceType)而不是 this.resolver.TryGet(的serviceType)在GetService的()实现是在我的情况的罪魁祸首。

From the hints in the answer by Remo and comment by Filip along with a significant amount of debugging time, I found out the use of this.resolver.Get(serviceType) instead of this.resolver.TryGet(serviceType) in GetService() implementation was the culprit in my situation.

我准备了详细的博客文章这个,但短期的是,一旦我们有NinjectDependencyResolver插入MVC使用线路:
GlobalConfiguration.Configuration.DependencyResolver =新NinjectDependencyResolver(内核);
我们不定义框架水平依赖绑定(如IHostBufferPolicySelector等),异常是由的get()方法的部分提出框架级依赖性时,他们没有通过Ninject解决。使用 TryGet()没有引发异常,框架回落到默认的依赖关系没有得到解决(a.ka.空)依赖像IHostBufferPolicySelector。因此,选项有

I plan a detailed blog post about this but the short of it is that once we have the NinjectDependencyResolver plugged into MVC using the line: GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); and we don't define Framework level dependency bindings (e.g. IHostBufferPolicySelector etc.), an exception is raised by the Get() method for some framework level dependencies when they are not resolved through Ninject. Using TryGet() does not raise an exception and the framework falls back to default dependencies for unresolved (a.ka. null) dependencies like IHostBufferPolicySelector. So, the options are


  1. 使用TryGet()方法来解决依赖关系。

  2. 裹获取的try / catch和丢弃的除外。

这篇关于Ninject抛出激活异常与多种组件的项目的WebAPI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆