【问题标题】:How to use Ninject with WebApi?如何将 Ninject 与 WebApi 一起使用?
【发布时间】:2013-03-18 20:48:33
【问题描述】:

我需要在 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();
    }
}
}

当我重建应用程序时,第一次加载很好,我的控制器得到了我的IDocumentSession。但是当我重新加载同一页面时,我得到了错误

“类型..没有默认构造函数”

【问题讨论】:

  • 我只能建议问题可能在于每个请求都调用WebApiApplication.DocumentStore.OpenSession()。这个方法有什么作用? DocumentStore 是什么?
  • DocumentStore 是 RavenDb 存储引用。会话是一个reven 会话。我从创建者的博客中获取了这段代码。在其他项目中运行良好

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


【解决方案1】:

这是我在 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;

    }
...
...
...

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-09
    • 2013-12-27
    • 2011-02-06
    • 1970-01-01
    • 2012-12-10
    • 2015-03-27
    • 2014-10-28
    • 1970-01-01
    相关资源
    最近更新 更多