网页API控制器没有默认构造函数。 Ninject依赖解析器问题 [英] Web API controller has no default constructor. Ninject dependency resolver issue

查看:878
本文介绍了网页API控制器没有默认构造函数。 Ninject依赖解析器问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的第一个API使用MVC工作。
我已经得到它通过创建一个API,并宣布/控制器中创建的数据,像这样的工作previously:

I'm working on my first API using MVC. I've gotten it working previously by creating an API and declaring/creating its data within the controller, like so:

public class ValuesController : ApiController
{
    private northwndEntities db = new northwndEntities();

    Product[] products = new Product[] 
    { 
        new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
        new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
        new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } 
    };

    public IEnumerable<Product> GetAllProducts()
    {
        return products;
    }

    public Product GetProduct(int id)
    {
        var product = products.FirstOrDefault((p) => p.Id == id);

        return (product);
    }
}

下面是我创建迅速用这个工作的模型:
Product.cs

Here is a model I created quickly to work with this: Product.cs

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Category { get; set; }
    public decimal Price { get; set; }
}

我不认为这是必要的,但这里是我用来拨打电话,尽管早期的测试,我只是导航到相应的URL,而不是试图华丽的脚本。

I don't believe it was necessary, but here is the script I used to make the call, even though for earlier testing, I just navigated to the appropriate URL, rather than trying to be fancy.

 <script>
        //var apiurl = "api/values";
        var apiurl = "api/ordersapi";
        $(document).ready(function() {
            $.getJSON(apiurl).done(function(data) {
                $.each(data, function(key, item) {
                    $('<li>', { text: formatItem(item) }).appendTo($('#products'));
                });
            });
        });

        function formatItem(item) {
            return item.Name + ": $" + item.Price;
        }

        function find() {
            var pId = $('#prdId').val();
            $.getJSON(apiurl + '/' + pId)
                .done(function (data) {
                    $('#product').text(formatItem(data));
                })
                .fail( function(jqxHr, textStatus, err) {
                    $('#product').text("Error: "+err);
                });
        }
    </script>

考虑到这一点,调用API /价值/ 2将返回数据,ID = 2
我能得到这个工作没有问题。
当然,我也确保改变试图调用,我快要下面勾勒出的API时,我使用的url变量。

With this in mind, a call to "api/values/2" would return the data for ID = 2 I can get this working no problem. Of course, I am also making sure to change the url variable I am using when trying to call the API that i'm about to outline below.

接下来,我想通过从我的pre-现有(数据库第一个样式)数据库调用加紧使用单独的API。

Next, I wanted to step up to using a separate API by calling from my pre-existing (database-first style) database.

我使用存储库模式和依赖注入所以这里的code为我的存储库(名为repo.cs),该API控制器(名为OrdersAPI控制器),以及我ninjectWebcommon.cs文件

I am using repository pattern and dependency injection so here is the code for my repository (named "repo.cs"), the API controller (named "OrdersAPI" controller), as well as my ninjectWebcommon.cs file

Repo.cs(repository类)

Repo.cs (the repository class)

public interface INorthwindRepository : IDisposable
{
    IQueryable<Order> GetOrders();
    Order GetOrderById(int id);
}

public class NorthwindRepository : INorthwindRepository
{
    private northwndEntities _ctx;

    public NorthwindRepository(northwndEntities ctx)
    {
        _ctx = ctx;
    }
    public IQueryable<Order> GetOrders()
    {        
        return _ctx.Orders.OrderBy(o => o.OrderID);
    }

    public Order GetOrderById(int id)
    {
        return _ctx.Orders.Find(id);
    }

    public void Dispose()
    {
        _ctx.Dispose();
    }
}

OrdersAPIController.cs

OrdersAPIController.cs

public class OrdersAPIController : ApiController
{

    private INorthwindRepository db;

    public OrdersAPIController(INorthwindRepository _db)
    {
        db = _db;
    }

    //api/ordersapi
    public IEnumerable<Order> Orders()
    {
        return db.GetOrders();
    }

//api/ordersapi/5
    public Order SpecificOrder(int id)
    {
        Order order = db.GetOrderById(id);

        return order;
    }
}

NinjectWebCommon.cs(*注意CreateKernel评论()方法)

NinjectWebCommon.cs (*Note the comment in CreateKernel() method)

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(RAD302PracticeAPI.App_Start.NinjectWebCommon), "Start")]

[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(RAD302PracticeAPI.App_Start.NinjectWebCommon), "Stop")]

namespace RAD302PracticeAPI.App_Start
{
using System;
using System.Web;

using Microsoft.Web.Infrastructure.DynamicModuleHelper;

using Ninject;
using Ninject.Web.Common;
using RAD302PracticeAPI.Models;
using System.Web.Http;
using Ninject.Web.Mvc;
using System.Web.Mvc;
//using System.Web.Http;
//using Ninject.Web.Mvc;

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

        //tried code from...
        //http://haacked.com/archive/2012/03/11/itrsquos-the-little-things-about-asp-net-mvc-4.aspx/
        //but it didnt work
        //GlobalConfiguration.Configuration.ServiceResolver.SetResolver(DependencyResolver.Current.ToServiceResolver());
    }

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

            RegisterServices(kernel);

            //this line is giving me an error saying:
            //"Cannot implicitly convert type 'Ninject.Web.Mvc.NinjectDependencyResolver' to
            //'System.Web.Http.Dependencies.IDependencyResolver'. An explicit conversion exists (are you missing a cast?)
            //However from one or two places here it has been recommended as a possible solution to solve
            //the dependency issue

            //one place is here: http://stackoverflow.com/questions/17462175/mvc-4-web-api-controller-does-not-have-a-default-constructor

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

            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<northwndEntities>().To<northwndEntities>();   
    }        
}
}

从我张贴在我的ninject.cs页面的评论区的联系,看来问题是,我需要设置一个依赖解析器了我的申请。
我认为这是为你,当你不使用API​​来完成,但在这种情况下,你必须这样做。我愿意在该修正。
所以,我的直觉是,我需要创建一个依赖解析器类,但该行我留在不工作的注释,而且据说是我需要的基础上,其他SO页面的解决方案。

From the link i've posted in the commented area of my ninject.cs page, it seems the problem is that I need to set a dependency resolver for my application. I THINK that this is done for you when you're not using an API, but in this situation you must. I'm open to correction on that. So, my hunch is that I need to create a dependency resolver class, but the line I left a comment on is not working, and is supposedly the solution I need, based on other SO pages.

感谢您给任何人谁需要时间来提供任何意见。
获得这个障碍可以让我得到我想要的是,至少目前。
我已经把一些精力来研究的问题是什么。只希望一个更有经验的头能发现一些微妙的。

Thank you to anybody who takes the time to offer any advice. Getting over this hurdle will allow me to get where I want to be, for now at least. I've put some effort into researching what the problem is. Just hoping a more experienced head can spot something subtle.

*更新:
当我取消这行

*Update: When I uncomment this line

GlobalConfiguration.Configuration.DependencyResolver =新NinjectDependencyResolver(内核);结果
即 - 有人建议,行至在我包括在我的code注释的链接添加,我得到的错误这一形象的 http://postimg.org/image/qr2g66yaj/

"GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);"
ie - the line that was recommended to add in the link that I included as a comment in my code, I get the error in this image http://postimg.org/image/qr2g66yaj/

当我有那行,那我给出的错误是这样的:
http://postimg.org/image/9wmfcxhq5/

And when I include that line, the error that i'm given is this: http://postimg.org/image/9wmfcxhq5/

推荐答案

您需要将您的资料库和您RegisterServices方法接口绑定:

You need to bind your repository and your interface on RegisterServices method:

kernel.Bind<INorthwindRepository>().To<NorthwindRepository>();

此外,您还必须检查你的项目配置。您可以下载,我已经从我的账户Github上创建了一个简单Ninject演示,并与你的项目进行比较。

Also, you have to check your project configuration. You can download a Simple Ninject demo that I've created from my Github account and compare it with your project.

这篇关于网页API控制器没有默认构造函数。 Ninject依赖解析器问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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