Anatolii Gabuza
Anatolii Gabuza

Reputation: 6260

WebAPI. Dependency injection with Ninject in case of inheritance

I'm pretty new to ASP.NET WebApi project, but hopefully I'll put everything straight enough. After creating couple CRUD Controllers a brilliant idea come to my mind - write generic base CRUD-web-API controller for all of them and do not mess with rewriting same code.
After successful implementation of such class I faced problem with dependency resolving which is still working fine for non-generic/-inherited controllers.
Simple request (GET, POST, etc.) gives:
Type 'UsersController' does not have a default constructor","ExceptionType":"System.ArgumentException"

Default constructor without injections works fine. Obviously I have a problem with Ninject configuration.

public abstract class BaseCRUDController<T> : ApiController where T : class, IClientEntity 
   {
      private readonly Repository<T> _repo;
      private readonly IDbContextDataProvider _context;

      // With this ctor everything works well
      public BaseCRUDController()
      {
         this._context = new ModelContext();
         this._repo = new Repository<T>(this._context);
      }

      // Injection is not working ((
      public BaseCRUDController(IDbContextDataProvider context)
      {
         this._context = context;
         this._repo = new Repository<T>(context);
      }

And concrete Controller for User entity:

public class UsersController : BaseCRUDController<User>
{      
  UsersController(IDbContextDataProvider context) : base(context) { }

  UsersController() : base() { }
}

And Ninject config itself:

public class DataProviderModule : NinjectModule
{
  public override void Load()
  {
     this.Bind<IDbContextDataProvider>().To<ModelContext>().InSingletonScope();
  }
}
public class NinjectResolver
{
  // Instantinate Ninject dependencies resolver
  public static System.Web.Http.Dependencies.IDependencyResolver GetConfiguredDependencyResolver()
  {
     IKernel kernel = new StandardKernel(new DataProviderModule());
     System.Web.Http.Dependencies.IDependencyResolver njResolver = new NinjectResolver(kernel);
     return njResolver;
  }
}

And Application_Start

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    var config = GlobalConfiguration.Configuration;
    config.DependencyResolver = NinjectResolver.GetConfiguredDependencyResolver();

    WebApiConfig.Register(config);

What am I doing wrong here?


NOTE: This approach works well if I have:

public class UsersController : ApiController
{      
  UsersController(IDbContextDataProvider context)
  {
     .... 
  }    

...

Upvotes: 0

Views: 1676

Answers (1)

Anatolii Gabuza
Anatolii Gabuza

Reputation: 6260

Oh.. I've spent hours trying different approaches. It was madness. And the funny part here is that Ninject is working well and code is correct except one accessibility modifier. Adding public modifier to UsersController ctor fixed the issue.

public class UsersController : BaseCRUDController<User>
{      
  public UsersController(IDbContextDataProvider context) : base(context) { }

...

PS. Write your code carefully...

Upvotes: 1

Related Questions