2

although there's a lot of questions round here about the same and I'm trying to follow this post that has been advised several times I can't make it work

http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/

I'm getting this error

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
An error occurred when trying to create a controller of type 'ProfileController'. Make sure that the controller has a parameterless public constructor.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace>
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Tracing.Tracers.HttpControllerActivatorTracer.<>c__DisplayClass2.<System.Web.Http.Dispatcher.IHttpControllerActivator.Create>b__0() at System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter traceWriter, HttpRequestMessage request, String category, TraceLevel level, String operatorName, String operationName, Action`1 beginTrace, Action execute, Action`1 endTrace, Action`1 errorTrace) at System.Web.Http.Tracing.Tracers.HttpControllerActivatorTracer.System.Web.Http.Dispatcher.IHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) at System.Web.Http.Tracing.Tracers.HttpControllerDescriptorTracer.<>c__DisplayClass2.<CreateController>b__0() at System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter traceWriter, HttpRequestMessage request, String category, TraceLevel level, String operatorName, String operationName, Action`1 beginTrace, Action execute, Action`1 endTrace, Action`1 errorTrace) at System.Web.Http.Tracing.Tracers.HttpControllerDescriptorTracer.CreateController(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()
</StackTrace>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'LoanBook.Api.Controllers.ProfileController' does not have a default constructor
</ExceptionMessage>
<ExceptionType>System.ArgumentException</ExceptionType>
<StackTrace>
at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
</StackTrace>
</InnerException>
</Error>

I don't know if this post is still relevant or there's another way of make this work. I'm working with 2012 but using web api2 in 4.5. The Ninject.Web.WebApi package has just released unstable versions yet so I'm not sure if it's an option.

EDIT: By the way, the solution is not place in the same project as an MVC one. Maybe that's an issue

Thanks

EDIT: The controller looks like this

public class ProfileController : BaseController
{
    private readonly IPersonService _personService;

    public ProfileController(IPersonService personService)
    {
        _personService = personService;
    }

    //.. Methods

}

The error is in the NinjectDependencyResolver shown in the post I mentioned, in this bit

public System.Collections.Generic.IEnumerable<object> GetServices(Type serviceType)
{
    if (resolver == null)
        throw new ObjectDisposedException("this", "This scope has been disposed");

    return resolver.GetAll(serviceType);
}

When it get to the return line

mitomed
  • 2,006
  • 2
  • 29
  • 58
  • Ok, as per my answer, i still can't see the parameterless ctor. Try adding that – jim tollan Nov 22 '13 at 09:03
  • Yes if I add it, it doesn't raise the error but the _personService is null as is not injected – mitomed Nov 22 '13 at 09:04
  • Best thing is to edit your post to show the ninject initialisation code as this could be where the issue lies. Also, post the line of code that is causing the failure – jim tollan Nov 22 '13 at 09:13
  • i edited my answer to show the expected ninject initialisation code that i'd expect to see. if you don't have this init code, then that is definitaly where the problem lies – jim tollan Nov 22 '13 at 09:44
  • possible duplicate of [Ninject binding with generic repository MVC returns error on Parameterless Constructor](http://stackoverflow.com/questions/18723935/ninject-binding-with-generic-repository-mvc-returns-error-on-parameterless-const) – Trevor Pilley Nov 22 '13 at 09:52

1 Answers1

1

It looks like the error is telling you that you need to create a parameterless constructor in the controller, this could be due to ninject RegisterServices() not being setup correctly.

You need the following to sort the error:

public ProfileController () { }

I'm therefore assuming that you have the required ioc constructor along the lines of:

public ProfileController (IPersonService personService) 
{
    _personService = personService;
}

[edit] - so i'd expect your NinjectWebCommon.cs (located in App_Start) to contain the following for everything to work:

private static void RegisterServices(IKernel kernel)
{
    /* other kernel.bind<>() setups */
    // assumes that your concrete class implementation
    // of IPersonService is called PersonService
    kernel.Bind<IPersonService>().To<PersonService>().InRequestScope();
}

hope this helps...

jim tollan
  • 22,305
  • 4
  • 49
  • 63
  • Yes, but I think in this case the injection is not working right? I mean, for using the PersonService I would need to instantiate it in that parameterless constructor – mitomed Nov 22 '13 at 08:58
  • See my edit, re the required 'pair' that you'd normally see. You'd then have your ninject initialisation to let the controller know which type of interface was to be converted to a concrete type – jim tollan Nov 22 '13 at 09:00
  • Yes, as far as I understand it's what I have in my controller so I shouldn't need the parameterless constructor. Thanks – mitomed Nov 22 '13 at 09:03
  • Ye, i agree for your use, there is no requiremen, however, the error message is hinting at wanting that :-) – jim tollan Nov 22 '13 at 09:05
  • Problem is that then it uses the parameterless so for using the service I need to instantiate it in the parameterless constructor and I'm not taking advantage of injection – mitomed Nov 22 '13 at 09:06
  • Hmmm... not sure i agree. IF, the ninject initialisation is set up correctly, then it should automatically set the required implementation up for you. If you are trying to instantiate a parameterless version in code and hope that it will inject, then this will not happen. The ioc only works via 'hidden' instantiation – jim tollan Nov 22 '13 at 09:09
  • Yes, I agree but the thing is that the error prompts me to use a parameterless constructor because it seems not to be able to use the one with the parameter. Therefore I would need to somehow populate the _personService in the controller and in the parameterless as you say no injection will occur so I will need to instantiate it – mitomed Nov 22 '13 at 09:12
  • Tahnks @jimtollan, I had something similar. I was missing the InRequestScope() but even adding it stills fails, maybe is something I have to do with a controller factory? – mitomed Nov 22 '13 at 09:51
  • mitomed, possibly the suggestion by trevor pilley could help: http://stackoverflow.com/questions/18723935/ninject-binding-with-generic-repository-mvc-returns-error-on-parameterless-const – jim tollan Nov 22 '13 at 10:05
  • Just a quick update. I couldn't make it work but following this it works fine http://www.strathweb.com/2012/05/using-ninject-with-the-latest-asp-net-web-api-source/ To be fair I'm not sure if I was doing something wrong with the other solutions as I was trying to inject a dependency that I hadn't instantiation for and with the second solution I got the proper error that made me solve it – mitomed Nov 25 '13 at 08:40