在WebAPI2中使用Ninject - 错误:确保控制器具有无参数的公共构造函数

时间:2015-03-25 13:35:44

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

我试图在WebAPI2应用程序中使用Ninject进行绑定和依赖注入,但显然我做错了。

我想根据Repository模式创建我的代码,所以我有一个界面,只有我需要的方法的简单定义:

public interface IAccountRepository
{
    AccountsOverview GetUserAccounts(HttpActionContext actionContext);
}

这是我实现IAccountRepository接口的类:

    public class AccountRepository : IAccountRepository
    {
        private readonly MockStorage mockStorage;

        public AccountRepository(MockStorage mockStorage)
        {
            this.mockStorage = mockStorage;
        }

        public AccountsOverview GetUserAccounts(HttpActionContext actionContext)
        {
            AccountsOverview accountsOverview = new AccountsOverview();
            var userName = actionContext.RequestContext.Principal.Identity.Name;
            Dictionary<string, List<Account>> accountsData = new Dictionary<string, List<Account>>();
            accountsData = MockStorage.GetAccountData();
            List<Account> userAccounts = accountsData.SelectMany(u => u.Value).ToList();

            accountsOverview.Accounts = userAccounts;
            accountsOverview.CurrentAccountsTotal = userAccounts.Where(a => a.AccountType == "Current card").Sum(a => a.Balance);
            accountsOverview.SavingAccountsTotal = userAccounts.Where(a => a.AccountType == "Saving card").Sum(a => a.Balance);
            accountsOverview.SavingAccountsTotalCurrency = "euro";
            accountsOverview.CurrentAccountsTotalCurrency = "euro";

            return accountsOverview;
        }
   }

MockStorage.cs是一个简单的类,它包含一些简单的测试数据,它有一个方法GetAccountData,它返回Dictionary类型。

public static Dictionary<string, List<Account>> GetAccountData()
{
      Dictionary<string, List<Account>> dictionaries = new Dictionary<string, List<Account>>();

      List<Account> NMoAccounts = new List<Account>(){
                                  new Account {AccountName="Credit card 1", AccountNumber=1234567890, AccountType="Credit card", AvailableBalance=234.4m, Balance=432.64m, Currency="euro", InterestRate=1.5m},
                                  new Account {AccountName="Credit card 3", AccountNumber=1357924680, AccountType="Credit card", AvailableBalance=24.06m, Balance=-32.123m, Currency="euro", InterestRate=1.5m},
                                  new Account {AccountName="Current card 10", AccountNumber=1357924680, AccountType="Current card", AvailableBalance=1.8m, Balance=2.3m, Currency="euro", InterestRate=1.5m},
                                  new Account {AccountName="Credit card 5", AccountNumber=1357924680, AccountType="Credit card", AvailableBalance=31.4m, Balance=-132.123m, Currency="euro", InterestRate=1.5m} 
                                  };

      dictionaries.Add("n.mosorinski", NMoAccounts);
      return dictionaries;
}

我已经制作了使用此功能的web api控制器:

public class BankAccountController : ApiController
{
    private IAccountRepository _accountsRepo;

    public BankAccountController(IAccountRepository accountsRepo)
    {
        this._accountsRepo = accountsRepo;  
    }

    [Route("accounts")]
    public AccountsOverview GetAccounts()
    {
        return _accountsRepo.GetUserAccounts(this.ActionContext);  
    }
}

在我的Startup.cs类中,我定义了Ninject内核如下:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();

        var webApiConfiguration = new HttpConfiguration();

        ConfigureOAuth(app);

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);
        app.UseNinjectMiddleware(CreateKernel);
        app.UseNinjectWebApi(webApiConfiguration);

    }
    private static StandardKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<MockStorage>().To<MockStorage>().InSingletonScope();
        kernel.Bind<IAccountRepository>().To<BankingPoCMobileBackend.Repository.Mock.AccountRepository>();
        return kernel;
    }
}

当我尝试从BankAccountsController调用GetAccounts方法时,我得到以下错误:

{
    "message": "An error has occurred.",
    "exceptionMessage": "An error occurred when trying to create a controller of type 'BankAccountController'. Make sure that the controller has a parameterless public constructor.",
    "exceptionType": "System.InvalidOperationException",
    "stackTrace": "   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n   at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
    "innerException": {
        "message": "An error has occurred.",
        "exceptionMessage": "Type 'BankingPoCMobileBackend.Controllers.BankAccountController' does not have a default constructor",
        "exceptionType": "System.ArgumentException",
        "stackTrace": "   at System.Linq.Expressions.Expression.New(Type type)\r\n   at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
    }
}

有没有人遇到过这种问题?我想我没有用Ninject做正确的事,但我不知道它可能是什么。是否有人遇到类似或相同的问题?

1 个答案:

答案 0 :(得分:0)

我不确定您使用的是哪个版本的Ninject.Web.WebApi,但我发现当我使用版本3.2.4.0时,我会遇到这个问题。

一旦我回到版本3.2.1.0,问题就消失了。我不确定引入该问题的版本或导致该问题的原因,但这解决了我的问题。