0

Here is my Error Message which is shown when I browse: ../api/User

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'RavenReader.Web.Controllers.UserController' does not have a default constructor
</ExceptionMessage>
<ExceptionType>System.ArgumentException</ExceptionType>
<StackTrace>
at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) 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>
</Error>

My Controller Classes are

public class BaseController : ApiController
    {
        private readonly ICookieStorageService _cookieStorageService;

        public BaseController(ICookieStorageService cookieStorageService) 
        {
            _cookieStorageService = cookieStorageService;
        }
    }

public class UserController : BaseController
    {
        private readonly RavenUserFacade _facade;
        private readonly ICookieStorageService _cookieStorageService;       
        public UserController(ICookieStorageService cookieStorageService, RavenUserFacade facade):base(cookieStorageService)
        {
            _facade = facade;
        }

        // GET api/User
        public IEnumerable<RavenUserView> Get()
        {
            var users = _facade.GetAllUser();
            return users.RavenUsers;
        }
        ..........................................
        ..........................................
    }

According to http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/ this blog I organized my NinjectDependencyScope class, NinjectDependencyResolver class and NinjectWebCommon as follows:

public class NinjectDependencyScope : IDependencyScope
    {
        private IResolutionRoot resolver;

        internal NinjectDependencyScope(IResolutionRoot resolver)
        {
            Contract.Assert(resolver != null);

            this.resolver = resolver;
        }

        public void Dispose()
        {
            var disposable = resolver as IDisposable;
            if (disposable != null)
                disposable.Dispose();

            resolver = null;
        }

        public object GetService(Type serviceType)
        {
            if (resolver == null)
                throw new ObjectDisposedException("this", "This scope has already been disposed");

            return resolver.TryGet(serviceType);
        }

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

            return resolver.GetAll(serviceType);
        }
    }
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
    {
        private IKernel kernel;

        public NinjectDependencyResolver(IKernel kernel)
            : base(kernel)
        {
            this.kernel = kernel;
        }

        public IDependencyScope BeginScope()
        {
            return new NinjectDependencyScope(kernel.BeginBlock());
        }
    }


public static class NinjectWebCommon
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start()
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        public static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            RegisterServices(kernel);
            GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(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<IDbFactory>().To<IDbFactory>().InSingletonScope();
            kernel.Bind<IUnitOfWork>().To<EFUnitOfWork>();
            kernel.Bind<IRavenUserRepository>().To<RavenUserRepository>();
            kernel.Bind<IRavenUserFacade>().To<RavenUserFacade>();
            kernel.Bind<ICookieStorageService>().To<CookieStorageService>();
            kernel.Bind<ICacheStorage>().To<HttpContextCacheAdapter>();
        }
    }

I am using visual Studio 2013 Ninject For MVC-3

cvbarros
  • 1,684
  • 1
  • 12
  • 19
Mojammel Haque
  • 651
  • 1
  • 7
  • 19
  • Did you remember setting this `DependencyResolver` to your `WebApiConfig`? This is usually done in `WebApiConfig.cs` – cvbarros Feb 06 '14 at 21:37
  • Thanks for your reply. I did a test Apicontroller in my same project where it work fine. The controller code is public class TestController : ApiController { private readonly ITest _test; public TestController(ITest test) { _test = test; } public string Get() { return _test.Name; } } and inside NinjectWebCommon.cs I bind as follows: kernel.Bind().To();. but when I work with my real controller it returns me no default constructor method error. – Mojammel Haque Feb 07 '14 at 07:46

2 Answers2

0

I am posting this answer in order to help you track down the root issue you are facing. It is not a solution but this is how I reproduced the exact same error you are having.

First of all, you should use a different implementation for the NinjectDependencyResolver. I've set this gist. The reason behind that is avoiding problem with scopes (specially singletons), which you can learn more about here.

Back to your problem, the error is in your bindings, somewhere. First, try removing the InSingletonScope from your IDbFactory. Then, try removing one dependency from your controller constructor and check if that works. Finally, strip out the base class and see if it works.

These steps are just to guide you track down the problem. I've replicated your scenario here and I couldn't face the same issue. My setup was like this:

public class BaseController : ApiController
{
    protected readonly IService _service;
    public BaseController(IService service)
    {
        _service = service;
    }
}

public class ValuesController : BaseController
{
    public ISomeOtherDependency Dependency { get; set; }

    public ValuesController(IService service, ISomeOtherDependency dependency) : base(service)
    {
        Dependency = dependency;
    }

    // GET api/values/5
    public string Get(int id)
    {
        return _service.CreatedAt.ToString("u");
    }
}

public interface ISomeOtherDependency
{

}

public class ConcreteDependency : ISomeOtherDependency
{
}

public interface IService
{
    DateTime CreatedAt { get; }
}

public class Service : IService
{
    public Service()
    {
        CreatedAt = DateTime.Now;
    }

    public DateTime CreatedAt { get; private set; }
}

And my bindings:

kernel.Bind<IService>().To<Service>(); // If I comment this, I get the same exception.
kernel.Bind<ISomeOtherDependency>().To<ConcreteDependency>();

But by commenting out one of these bindings, I get the exact same error as you:

ValuesController' does not have a default constructor

I hope this gets you on the right track to fix your issue.

Community
  • 1
  • 1
cvbarros
  • 1,684
  • 1
  • 12
  • 19
0

Thanks for your reply. I followed each your steps but same results here. Finally I debugged by bindings that belongs inside NinjectWebCommon.cs and I found a problem here. While debugging it shows me following problem: Locating source for Bootstrapper.cs not found You need to find Bootstrapper.cs to view the source for the current call stack frame

'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs'. Checksum: MD5 {13 3e b1 f3 ba a7 65 14 f6 dc 4d f1 dd aa 21 bf}
The file 'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs' does not exist.
Looking in script documents for 'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs'...
Looking in the projects for 'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs'.
The file was not found in a project.
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\crt\src\'...
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\crt\src\vccorlib\'...
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\atlmfc\src\mfc\'...
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\atlmfc\src\atl\'...
Looking in directory 'C:\Program Files\Microsoft Visual Studio 11.0\VC\atlmfc\include'...
The debug source files settings for the active solution indicate that the debugger will not ask the user to find the file: c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs.
The debugger could not locate the source file 'c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs'.
Mojammel Haque
  • 651
  • 1
  • 7
  • 19