ASP.NET 使用 ninject 绑定 Web API

本文关键字:Web API 绑定 ninject NET 使用 ASP | 更新日期: 2023-09-27 18:36:04

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

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

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

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

我没有对通过 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>();
    }        
}

我的控制器看起来像

   private readonly IConsumerRepository _repository;
    public ConsumerController(IConsumerRepository repository)
    {
        _repository = repository;
    }
    [HttpGet]
    public IQueryable<Consumer> Get(Guid id)
    {
        return _repository.Get(id).AsQueryable();
    }

我需要做什么才能让 api 控制器使用 ninject?

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

我尝试了您的建议迈克尔,但是在更改了网络共享.cs后,将此

  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>();
    }

我在以下情况下收到错误

var kernel = new StandardKernel();

被称为

来自程序集"Ninject.Web.WebApi, Version=3.0.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7"的类型"Ninject.Web.WebApi.Filter.DefaultFilterProvider"中的方法"GetFilters"没有实现。

我错过了什么?

ASP.NET 使用 ninject 绑定 Web API

我问过Brad Wilson,它在MVC4 RC中发生了变化。

GlobalConfiguration.Configuration.ServiceResolver

已移至 GlobalConfiguration.Configuration.DependencyResolver

使用此实现为您的 Web API 创建 Ninject 依赖项解析器:https://gist.github.com/2417226

NinjectWebCommon.cs中:

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

此一般错误消息

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

如果未将构造函数设为公共,或者 IoC 容器可能由于缺少参数而无法解析依赖项,也会发生这种情况。

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

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

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

对于在搜索"...没有默认构造函数'寻找一种简单的方法来调试静默失败的配置:

    删除构造函数
  1. 注入的对象,直到可以调用构造函数
  2. 对于每个以前注入的、现在未初始化的对象,使用以下方法调用:

ServiceLocator.Current.GetInstance<[OBJ-TYPE]>()

有问题的对象将导致带有描述性消息的激活异常。你会有一些东西要去。

请记住在修复后删除对服务定位器的调用。即。建议在调试外部使用服务定位器反模式。

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

此外,Mark Seeman在WebAPI的DI方面有一篇很好的文章。

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

从普洛出发:

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

以上必须在全局中执行

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

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

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

正在呼叫:

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

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

而是必须更新为:

builder.RegisterApiControllers(Assembly.GetCallingAssembly());

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

控制器:

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

依赖关系:

public class ContestEntryService : IContestEntryService
{
    public ContestEntryService(IContestsContext contestsContext)
    {

配置不正确:

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

正确的配置:

    private static void RegisterServices(IKernel kernel)
    {
         kernel.Bind(x =>
            x.FromAssembliesMatching("MyNameSpace.*")
             .SelectAllClasses()
             .BindAllInterfaces()
         );
         kernel.ReBind<IContestsContext>()
              .To<ContestsContext>()
              .InRequestScope();

一般来说,Ninject 在报告此类错误方面非常出色,所以我真的被扔了一遍!

我知道

这是一个旧帖子,但我在某个链接中找到了解决方案,所以在这里分享。希望对您有所帮助。

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

如果有人仍然遇到问题,请听听由于某种原因,ninject 在 MVC 4 中无法正常工作。在您的 Web API 中,您需要编写此代码

public DefaultController() : base() { }  

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

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

请记住,您还必须在此处访问数据库类,例如:

DefaultConnection context = new DefaultConnection(); 

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

我也有这条错误消息,但事实证明我的一个接口实际上并没有被任何类实现(我忘了将其添加到类声明中)。