0

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?

Ivo Coumans
  • 759
  • 8
  • 23
  • 1
    check this out: http://stackoverflow.com/questions/24254189/webapi-make-sure-that-the-controller-has-a-parameterless-public-constructor – İsmet Alkan Nov 05 '14 at 08:10
  • 2
    Hmmmmmmm.... i think firstly take a look at this [video](https://skillsmatter.com/skillscasts/5688-orms-you-re-doing-it-wrong). Then rework your app. – Callum Linington Nov 05 '14 at 08:10
  • After seeing about a million articles on why repositories are the best thing since discovering fire, that video looks very interesting. I'll take a look at it when I get home. – Ivo Coumans Nov 05 '14 at 09:02

1 Answers1

1

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.

Callum Linington
  • 14,213
  • 12
  • 75
  • 154
  • I've been so focused on doing things "the right way" that I've completely lost track of what matters - getting it done. After taking a step backwards, I realized that my approach was indeed unnecessary for the project. – Ivo Coumans Nov 05 '14 at 09:00
  • 1
    Above is a "right way", not because of opinion, but because of what it does. It does dispose of the context properly in the request scope. It does expose useful functions on the `DbContext`. When thinking about what you need to do in a project, think about what is needed by the frameworks you use first. – Callum Linington Nov 05 '14 at 09:07