Ivo Coumans
Ivo Coumans

Reputation: 759

Resolve controller: "Make sure that the controller has a parameterless public constructor"

I have several Web API controllers in my project. After a lot of redundant code, I've refactored them into the code below, which seemed to be highly reusable. However, I'm suddenly getting the error Make sure that the controller has a parameterless public constructor, which seems to be caused by Ninject not being able to resolve the controller bindings. I'm not sure how to bind them.

My code:

public interface IController<T, TK>
{
    DataSourceResult Get(DataSourceRequest request);
    T Get(TK id);
    HttpResponseMessage Post(T model);
    T Put(T model);
    TK Delete(TK id);
}

public abstract class BaseController<T, TK> : ApiController, IController<T, TK>
{
    private readonly IRepository<T, TK> repository;

    public BaseController(IRepository<T, TK> repository)
    {
        this.repository = repository;
    }

    /* methods here */
}

public class ReceiptsController : BaseController<ReceiptViewModel, long>
{
    public ReceiptsController(IRepository<ReceiptViewModel, long> repository) :
        base(repository)
    {
    }
}

In the ninject RegisterServices method, I've tried the following:

kernel.Bind<IController<OntvangstViewModel, long>>().To<OntvangstenController>();
kernel.Bind<BaseController<OntvangstViewModel, long>>().To<OntvangstenController>();

But neither seem to work. Is my implementation or inheritance wrong? Or should I bind them differently?

Upvotes: 0

Views: 287

Answers (1)

Callum Linington
Callum Linington

Reputation: 14417

There is so much discussion around Repositories that you could read for days. One thing that I could point out to make your code better is this:

public class ReceiptsController : ApiController
{
    public ReceiptsController()
    {
    }

    public List<Receipt> Get()
    {
        List<Receipt> receipts = new List<Receipt>();
        using (var context = new DbContext())
        {
            receipts = context.Receipts.ToList();
        }

        return View(receipts);
    }
}

You don't need a repository. They don't really give you anything in benefits. In fact they remove a lot of the goodness from the DbContext. In my example, you don't have to worry about any injection at all.

Take a close look at DbContext.

It is wrapped in a using. That means, when you are done using the database connection, or your database transactions throw an error then your connection gets disposed of properly. Something that doesn't seem to be happening in your scenario - AFAIK.

Secondly, my example takes less time to write because I haven't written; a controller class, its interface, a generic implementation for a repository, a concrete implementation for a repository. So that's 4 classes that I have circumvented.

IMHO - my way is tonnes easier, less code to write. Safer.

Upvotes: 1

Related Questions