c# - 如何将 Ninject 与 WebApi 一起使用?

标签 c# asp.net-web-api ninject

我需要在 Web APi 应用程序上使用 Ninject(我使用空的 Web API 模板创建了它)。

我安装了以下 nuget 包:

Ninject.Web.WebApi

Ninject.MVC3

这是我的application_start

protected void Application_Start()
    {

        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);


    }

我的 Ninject.Web.Common

[assembly: WebActivator.PreApplicationStartMethod(typeof(rb.rpg.backend.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(rb.rpg.backend.App_Start.NinjectWebCommon), "Stop")]

namespace rb.rpg.backend.App_Start
{
    using System;
    using System.Web;

using Microsoft.Web.Infrastructure.DynamicModuleHelper;

using Ninject;
using Ninject.Web.Common;
using Raven.Client;
using RemiDDD.Framework.Cqrs;    
using System.Web.Http.Dependencies;
using System.Web.Http;
using System.Collections.Generic;
using Ninject.Web.WebApi;

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);
        //System.Web.Mvc.DependencyResolver.SetResolver(new LocalNinjectDependencyResolver(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<IDocumentSession>()
          .ToMethod(ctx => WebApiApplication.DocumentStore.OpenSession())
          .InRequestScope();
        kernel.Bind<MessageProcessor>()
            .ToMethod(ctx =>
            {
                var MessageProcessor = new MessageProcessor(kernel);

                /*...*/
                return MessageProcessor;
            })
            .InSingletonScope();
    }
}
}

当我重建应用程序时,第一次加载正常,我的 Controller 获取了我的 IDocumentSession。但是当我重新加载同一个页面时,我得到了错误

"the type .. has no default constructor"

最佳答案

以下是我在 Web API 项目中的设置方式:

从 nuget.org 下载常规 Ninject

PM> Install-Package Ninject

在您的 Web API 项目中添加名为 Infrastructure 的新文件夹,在该文件夹中创建 2 个文件:

NInjectDependencyScope.cs 内容:

public class NInjectDependencyScope : IDependencyScope
{
    private IResolutionRoot _resolutionRoot;

    public NInjectDependencyScope(IResolutionRoot resolutionRoot)
    {
        _resolutionRoot = resolutionRoot;
    }

    public void Dispose()
    {
        var disposable = _resolutionRoot as IDisposable;

        if (disposable != null)
            disposable.Dispose();

        _resolutionRoot = null;
    }

    public object GetService(Type serviceType)
    {
        return GetServices(serviceType).FirstOrDefault();
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        var request = _resolutionRoot.CreateRequest(serviceType, null, new IParameter[0], true, true);

        return _resolutionRoot.Resolve(request);
    }
}

NInjectDependencyResolver.cs 内容:

public class NInjectDependencyResolver : NInjectDependencyScope, IDependencyResolver
{
    private IKernel _kernel;

    public NInjectDependencyResolver(IKernel kernel) : base(kernel)
    {
        _kernel = kernel;
    }

    public IDependencyScope BeginScope()
    {
        return new NInjectDependencyScope(_kernel.BeginBlock());
    }
}

Global.asax 文件的 Application_Start() 方法中添加:

//Ninject dependency injection configuration
        var kernel = new StandardKernel();
        kernel.Bind<IXyzRepository>().To<EFXyzRepository>();

        GlobalConfiguration.Configuration.DependencyResolver = new NInjectDependencyResolver(kernel);

这样您的最终 Global.asax 文件将如下所示:

public class XyzApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        //Ninject dependency injection configuration
        var kernel = new StandardKernel();
        //Your dependency bindings
        kernel.Bind<IXyzRepository>().To<EFXyzRepository>();            

        GlobalConfiguration.Configuration.DependencyResolver = new NInjectDependencyResolver(kernel);
    }
}

就是这样!

这是一个用法示例:

public class PersonController : ApiController
{
    private readonly IXyzRepository repository;

    public PersonController(IXyzRepository repo)
    {
        repository = repo;

    }
...
...
...

希望对您有所帮助。

关于c# - 如何将 Ninject 与 WebApi 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15486645/

相关文章:

c# - 在 try-catch 中包装 specflow 场景

C# 图像旋转

c# - 从自定义 PostSharp 属性内部访问请求 header

c# - Ninject 错误 : Sequence contains no elements

c# - 注入(inject)带有参数的单例

c# - 将 C# 哈希函数转换为 C++

c# - 如何使用 ASP.NET 为文件夹设置特定的 404?

asp.net - POST 参数未使用 VBA 传递到 Web API

c# - 在 WebApi Controller 中读取 HttpContent

mocking - 如何使用Ninject.MockingKernel?