C# 使用 ninject 绑定 ASP.NET Web API

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10849132/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:30:36  来源:igfitidea点击:

ASP.NET Web API binding with ninject

c#asp.net-mvc-4asp.net-web-apiwcf-web-api

提问by Diver Dan

I have just installed the mvc4 rc update and I am trying to build an api application with little luck.

我刚刚安装了 mvc4 rc 更新,我正在尝试构建一个 api 应用程序,但运气不佳。

I am using ninject but cant get my controllers to load. I keep getting an error

我正在使用 ninject 但无法加载我的控制器。我不断收到错误

Type 'Api.Controllers.ConsumerController' does not have a default constructor

类型 'Api.Controllers.ConsumerController' 没有默认构造函数

I am very new to mvc and using injection so please bear with me.

我对 mvc 和使用注入非常陌生,所以请耐心等待。

I havent done anything special to the default binding that is created via nuget

我没有对通过 nuget 创建的默认绑定做任何特别的事情

 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);
        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<IConsumerRepository>().To<ConsumerRepository>();
    }        
}

My controller looks like

我的控制器看起来像

   private readonly IConsumerRepository _repository;

    public ConsumerController(IConsumerRepository repository)
    {
        _repository = repository;
    }

    [HttpGet]
    public IQueryable<Consumer> Get(Guid id)
    {
        return _repository.Get(id).AsQueryable();
    }

What do I need to do to get the api controllers to work with ninject?

我需要做什么才能让 api 控制器与 ninject 一起工作?

Sorry if this is simple stuff

对不起,如果这是简单的东西

I tried your suggestion Michael however after changing the the webcommon.cs to this

但是,在将 webcommon.cs 更改为此后,我尝试了您的建议 Michael

  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<IConsumerRepository>().To<ConsumerRepository>();
    }

I get an error when

出现错误时

var kernel = new StandardKernel();

is called

叫做

Method 'GetFilters' in type 'Ninject.Web.WebApi.Filter.DefaultFilterProvider' from assembly 'Ninject.Web.WebApi, Version=3.0.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7' does not have an implementation.

来自程序集 'Ninject.Web.WebApi.Filter.DefaultFilterProvider' 的类型 'GetFilters' 中的方法 'GetFilters' 没有实现。

What am I missing?

我错过了什么?

采纳答案by Michael Baird

I asked Brad Wilsonabout this and it has changed in MVC4 RC.

我向Brad Wilson询问了这个问题,它在 MVC4 RC 中发生了变化。

GlobalConfiguration.Configuration.ServiceResolverhas been moved to GlobalConfiguration.Configuration.DependencyResolver

GlobalConfiguration.Configuration.ServiceResolver已移至GlobalConfiguration.Configuration.DependencyResolver

Use this implementation to create a Ninject DependencyResolver for your Web Api: https://gist.github.com/2417226

使用此实现为您的 Web Api 创建 Ninject DependencyResolver:https: //gist.github.com/2417226

In NinjectWebCommon.cs:

NinjectWebCommon.cs 中

// Register Dependencies
RegisterServices(kernel);

// Set Web API Resolver
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);

回答by jflood.net

have you registered the container with the frawework? I prefer using autofac, here is an example of how to use autofac with API. http://alexmg.com/post/2012/03/08/Autofac-ASPNET-Web-API-%28Beta%29-Integration.aspx

您是否已使用 frawework 注册容器?我更喜欢使用 autofac,这里是一个如何使用 autofac 和 API 的例子。http://alexmg.com/post/2012/03/08/Autofac-ASPNET-Web-API-%28Beta%29-Integration.aspx

Also, Mark Seeman has a good post on DI in general with WebAPI

此外,Mark Seeman 有一篇关于 DI 的好文章,一般使用 WebAPI

http://blog.ploeh.dk/2012/03/20/RobustDIWithTheASPNETWebAPI.aspx

http://blog.ploeh.dk/2012/03/20/RobustDIWithTheASPNETWebAPI.aspx

From Ploeh:

来自 Ploeh:

GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
    t => this.container.Kernel.HasComponent(t) ?
        this.container.Resolve(t) :
        null,
    t => this.container.ResolveAll(t).Cast<object>());

The above has to be performed in the global.asax

以上必须在 global.asax 中执行

回答by badikumar

This generic error message

此通用错误消息

Type 'Api.Controllers.ConsumerController' does not have a default constructor

类型 'Api.Controllers.ConsumerController' 没有默认构造函数

can also occur if you do not make your constructor public, or the dependency cannot be resolved by the IoC container maybe because of a missing argument.

如果您不公开构造函数,或者由于缺少参数,IoC 容器无法解析依赖项,也会发生这种情况。

The error message is misleading to say the least.

至少可以说,错误消息具有误导性。

回答by timothyclifford

Hopefully this helps someone else...

希望这对其他人有帮助...

I was having the same issue and it was related to me moving class responsible for registering assembly in charge of initializing controllers. Moved out of web into framework project.

我遇到了同样的问题,这与我移动负责注册负责初始化控制器的程序集的类有关。移出网络进入框架项目。

Using Autofac but same would apply for other containers.

使用 Autofac 但同样适用于其他容器。

Was calling:

打电话给:

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

Which works fine when it's within web application, but threw above exception when moved to framework project as the executing assembly no longer contains the controllers.

当它在 Web 应用程序中时工作正常,但在移动到框架项目时抛出上述异常,因为执行程序集不再包含控制器。

Instead had to update to:

相反,必须更新为:

builder.RegisterApiControllers(Assembly.GetCallingAssembly());

回答by John Culviner

It seems Ninject didn't throw an exception as it generally does when your IOC dependencies aren't quite set up right. Instead it made it look like I hadn't registered the WebAPI dependency resolver which I certainly did. Here was my solution to this problem but from what I've found it could be MANY DIFFERENT types of setup issues. Just re-check everything in the dependency chain. Hopefully it helps someone!

似乎 Ninject 并没有像通常在您的 IOC 依赖项设置不正确时那样抛出异常。相反,它看起来好像我没有注册我当然注册的 WebAPI 依赖项解析器。这是我对这个问题的解决方案,但据我所知,它可能是许多不同类型的设置问题。只需重新检查依赖链中的所有内容。希望它可以帮助某人!

The controller:

控制器:

public class ContestsController : ApiController
{
    //Ninject wouldn't inject this CTOR argument resulting in the error
    public ContestsController(IContestEntryService contestEntryService)
    {

The dependency:

依赖:

public class ContestEntryService : IContestEntryService
{

    public ContestEntryService(IContestsContext contestsContext)
    {

The incorrect configuration:

错误的配置:

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IContestsContext>()
              .To<ContestsContext>()
              .InRequestScope();

        kernel.Bind(x =>
            x.FromAssembliesMatching("MyNameSpace.*")
             .SelectAllClasses()
             .BindAllInterfaces()
         );

The correct configuration:

正确的配置:

    private static void RegisterServices(IKernel kernel)
    {
         kernel.Bind(x =>
            x.FromAssembliesMatching("MyNameSpace.*")
             .SelectAllClasses()
             .BindAllInterfaces()
         );

         kernel.ReBind<IContestsContext>()
              .To<ContestsContext>()
              .InRequestScope();

Generally Ninject is pretty good about reporting these sorts of errors so I really got thrown for a loop on this one!

一般来说,Ninject 在报告这些类型的错误方面做得很好,所以我真的被这个错误抛在了脑后!

回答by Rasshme Chawla

I know its an old post, but i found the solution at some link so sharing here. Hope it helps.

我知道它是一个旧帖子,但我在某个链接上找到了解决方案,所以在这里分享。希望能帮助到你。

http://weblogs.asp.net/hajan/archive/2013/03/16/quick-tip-how-to-make-ninject-work-with-asp-net-web-api.aspx?CommentPosted=true#commentmessage

http://weblogs.asp.net/hajan/archive/2013/03/16/quick-tip-how-to-make-ninject-work-with-asp-net-web-api.aspx?CommentPosted=true#评论留言

回答by Ryan Spears

You can install the NuGet package WebApiContrib.IoC.Ninject and add the following line of code to NinjectWebCommon.cs

您可以安装 NuGet 包 WebApiContrib.IoC.Ninject 并将以下代码行添加到 NinjectWebCommon.cs

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

回答by user3247368

if any anyone is still having problems, please listen for some reason ninject is not working how we would expect with mvc 4. In your web api, you need to write this code

如果任何人仍然有问题,请听听出于某种原因 ninject 不能像我们期望的那样使用 mvc 4。在您的 web api 中,您需要编写此代码

public DefaultController() : base() { }  

This removes the error saying about no default constructor, then when you need to get your data from the get method write this code:

这消除了关于没有默认构造函数的错误,然后当您需要从 get 方法获取数据时,请编写以下代码:

public IEnumerable<YourModelGoesHere> Get() 
{
    return context.YourData;  
} 

Keep in mind, you will have to access your db class here as well, for instance:

请记住,您还必须在此处访问您的 db 类,例如:

DefaultConnection context = new DefaultConnection(); 

回答by Andrey Burykin

just install Ninject.MvcXXX package, where XXX - version of MVC...

只需安装 Ninject.MvcXXX 包,其中 XXX - MVC 版本...

回答by Mark Cidade

I had this error message, too, but it just turned out that one of my interfaces weren't actually implemented by any classes (I forgot to add it to the class declaration).

我也有这个错误消息,但结果是我的一个接口实际上没有被任何类实现(我忘记将它添加到类声明中)。