1

I'm developing an ASP.NET Web Api 2.2 web service with .NET Framework 4.6.2.

Yes, there are a lot of questions similar to mine but and I did it everything they suggest in their answers and I have the following error:

{
  "Message": "Error.",
  "ExceptionMessage": "Error trying to create a controller of type 'PrintedCodesStatisticsController'. Ensure that the controller has a public constructor without parameters.",
  "ExceptionType": "System.InvalidOperationException",
  "StackTrace": "   en System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n   en System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n   en System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
  "InnerException": {
    "Message": "Error.",
    "ExceptionMessage": "Type 'MyProject.WebApi.Controllers.PrintedCodesStatisticsController' doesn't have a predefined constructor",
    "ExceptionType": "System.ArgumentException",
    "StackTrace": "   en System.Linq.Expressions.Expression.New(Type type)\r\n   en System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n   en System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   en System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
  }
}

The packages that I'm using on my project are:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="6.1.3" targetFramework="net462" />
  <package id="log4net" version="2.0.5" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Client.es" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Core.es" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.WebHost.es" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net462" />
  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net462" />
  <package id="Ninject" version="3.2.2.0" targetFramework="net462" />
  <package id="Ninject.MVC5" version="3.2.1.0" targetFramework="net462" />
  <package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net462" />
  <package id="Ninject.Web.Common.WebHost" version="3.2.3.0" targetFramework="net462" />
  <package id="WebActivatorEx" version="2.2.0" targetFramework="net462" />
</packages>

And I'm sure I'm using NinjectDependenciaResolver because I have debugged it and it stops on it sets GlobalConfiguration.Configuration.DependencyResolver.

NinjectDependencyResolver is:

using Ninject;
using System.Web.Http.Dependencies;

namespace AnotherProject.Web.Common.Ninject
{
    /// <summary>
    /// Used to resolve dependencies.
    /// </summary>
    public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
    {
        public NinjectDependencyResolver(IKernel kernel)
            : base(kernel)
        { }

        public IDependencyScope BeginScope()
        {
            return this;
        }
    }
}

And NinjectDependencyScope is:

public class NinjectDependencyScope : IDependencyScope
{
    private readonly IKernel _container;

    public IKernel Container
    {
        get { return _container; }
    }

    public NinjectDependencyScope(IKernel container)
    {
        _container = container;
    }

    public object GetService(Type serviceType)
    {
        return _container.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.GetAll(serviceType);
    }

    public void Dispose()
    {
        // noop
    }
}

And finally, NinjectConfigurator is:

public class NinjectConfigurator
{
    /// <summary>
    /// Entry method used by caller to configure the given 
    /// container with all of this application's 
    /// dependencies. Also configures the container as this
    /// application's dependency resolver.
    /// </summary>
    public void Configure(IKernel container)
    {
        // Add all bindings/dependencies
        AddBindings(container);

        // Use the container and our NinjectDependencyResolver as
        // application's resolver
        var resolver = new NinjectDependencyResolver(container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }

    /// <summary>
    /// Add all bindings/dependencies to the container
    /// </summary>
    private void AddBindings(IKernel container)
    {
        [ ... ]
    }
}

How can I solve this error?

3
  • That error message is typical if somewhere your Interface is not inhereted by your class ... It would be good if you show code where you bind your clases to the interfaces - might be a source of the error Commented Nov 29, 2016 at 16:56
  • What are the dependencies for PrintedCodesStatisticsController? Can you provide those details? What does the constructor for PrintedCodesStatisticsController looks like? Commented Nov 29, 2016 at 17:32
  • Thanks but the problem was that I was injecting an Interface that it hasn't been defined on NinjectConfigurator class. Commented Nov 30, 2016 at 8:22

2 Answers 2

1

There are few ways to register Ninject IoC container. One way is to use WebActivator.

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(NinjectWebCommon), "Stop")]

You can download my sample project at GitHub. The original project is for MVC, so you just need to replace line 30 and 31 with the following two line for Web API.

var resolver = new NinjectDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;

FYI: There are two main files for Ninject in my sample project - NinjectConfigurator.cs and NinjectWebCommon.cs.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks but the problem was that I was injecting an Interface that it hasn't been defined on NinjectConfigurator class.
I'm glad that you figure it out.
0

For making Ninject Dependency Injection framework work with ASP.NET WebApi 2.2 with .NET Framework 4.6.2, please install following packages, pay attention to the Ninject packages and the versions.

Ninject 3.2.0.0
Ninject.MVC5 3.2.1.0
Ninject.Web.Common 3.2.0.0
Ninject.Web.WebApi 3.2.4.0
Ninject.Web.WebApi.WebHost 3.2.4.0

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="6.1.3" targetFramework="net462" />
  <package id="log4net" version="2.0.5" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Client.es" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Core.es" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.WebHost.es" version="5.2.3" targetFramework="net462" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net462" />
  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net462" />
  <package id="Ninject" version="3.2.0.0" targetFramework="net462" />
  <package id="Ninject.MVC5" version="3.2.1.0" targetFramework="net462" />
  <package id="Ninject.Web.Common" version="3.2.0.0" targetFramework="net462" />
  <package id="Ninject.Web.Common.WebHost" version="3.2.0.0" targetFramework="net462" />
  <package id="Ninject.Web.WebApi" version="3.2.4.0" targetFramework="net462" />
  <package id="Ninject.Web.WebApi.WebHost" version="3.2.4.0" targetFramework="net462" />
  <package id="WebActivatorEx" version="2.2.0" targetFramework="net462" />
</packages>

Here is the NijectWebCommon.cs located in App_Start, please make sure the types you registered in RegisterServices method are correctly registered eg..

kernel.Bind<IEmployeeRepository>().To<EmployeeRepository>(); instead of
kernel.Bind<IEmployeeRepository, EmployeeRepository>();

NijectWebCommon.cs

using MyData;
using System;
using System.Web;

using Microsoft.Web.Infrastructure.DynamicModuleHelper;

using Ninject;
using Ninject.Web.Common;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(MyTestApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(MyTestApp.App_Start.NinjectWebCommon), "Stop")]

namespace MyTestApp.App_Start
{


    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>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

                RegisterServices(kernel);
                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IEmployeeRepository>().To<EmployeeRepository>();
        }        
    }
}

Here is the sample api controller

using System.Web.Http;
using MyData;

namespace MyTestApp.Controllers
{
    public class MyTestController : ApiController
    {
        private readonly IEmployeeRepository _employeeRepository;
        public MyTestController(IEmployeeRepository employeeRepository)
        {
            _employeeRepository = employeeRepository;
        }


        public IHttpActionResult Get()
        {
            var employees = _employeeRepository.GetEmployees();
            return Ok(employees);
        }
    }
}

1 Comment

Thanks but the problem was that I was injecting an Interface that it hasn't been defined on NinjectConfigurator class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.