I'm migrating an MVC/WebApi application to using Owin, but after installing all the components, and moving all configuration from the globals.asax to Startup.cs i'm getting the error Type 'EventController' does not have a default constructor
.
It seems how i've got ninject configured isn't working correctly. Can anyone spot the error?
EventController
public class EventController : BaseApiController
{
private readonly IAttendeeService attendeeService;
private readonly IEventService eventService;
private readonly IExcelService excelService;
public EventController(IEventService eventService, IAttendeeService attendeeService, IExcelService excelService)
{
this.attendeeService = attendeeService;
this.eventService = eventService;
this.excelService = excelService;
}
}
Here's the startup.cs class
using System.Linq;
using System.Net.Http.Formatting;
using System.Reflection;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Filanthropy.Core;
using Filanthropy.Model.Models;
using Filanthropy.Services;
using Filanthropy.Web;
using Filanthropy.Web.App_Start;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin;
using Microsoft.Owin.Cors;
using Newtonsoft.Json.Serialization;
using Ninject;
using Ninject.Web.Common;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
[assembly: OwinStartup(typeof(Startup))]
namespace Filanthropy.Web
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration httpConfig = new HttpConfiguration();
ConfigureOAuthTokenGeneration(app);
ConfigureWebApi(httpConfig);
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(httpConfig);
app.MapSignalR();
app.UseNinjectMiddleware(CreateKernel).UseNinjectWebApi(httpConfig);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AutoMapperConfig.Configure();
}
private void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(FilanthropyContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Plugin the OAuth bearer JSON Web Token tokens generation and Consumption will be here
}
private void ConfigureWebApi(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
private static StandardKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
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<IDbContext>().To<FilanthropyContext>().InRequestScope();
kernel.Bind<IEventService>().To<EventService>().InRequestScope();
kernel.Bind<IAttendeeService>().To<AttendeeService>().InRequestScope();
kernel.Bind<IProjectService>().To<ProjectService>().InRequestScope();
kernel.Bind<IPaymentService>().To<PaymentService>().InRequestScope();
kernel.Bind<IPledgeService>().To<PledgeService>().InRequestScope();
kernel.Bind<IExcelService>().To<ExcelService>();
kernel.Bind<IUserStore<ApplicationUser>>()
.To<UserStore<ApplicationUser>>()
.WithConstructorArgument("context", context => kernel.Get<FilanthropyContext>());
}
}
}
The error message
can be misleading, because you may also see it in a lot of other situations when there is nothing wrong with the controller or the way Ninject is set up.
Try again with a more simple controller, which only has a single dependency, which
Does this work? Then, most likely, there is something wrong with your other dependencies, such as:
RegisterServices
.All problems with setting up Ninject that I've had were due to bogus dependencies, and this is not unlikely if you add Ninject (or dependency injection) to a project "late", and you have to refactor to make it testable.
Do not modify the
NinjectWebCommon.cs
file, other than adding service registrations. As long as you have installed all the required packages:Ninject
Ninject.Web.Common
Ninject.Web.Common.WebHost
Ninject.Web.WebApi
Ninject.Web.WebApi.WebHost
then Ninject should work without modifications, and any of the modifications suggested in other answers or other questions will only create new problems and send you on a round-trip through StackOverflow questions asked by people who tried these modifications and ran into problems.