I've read every Stack Overflow question I can find but to no avail. When I installed the Ninject packages through NuGet, the NinjectWebCommon.cs class was not installed, so I coded up my own (below). I installed Ninject, Ninject.WebCommon, Ninject.Webcommon.Webhost, Ninject.WebApi, Ninject.WebApi.DependencyResolver. However, I am getting the well-known message in my controller that I must have a parameterless controller, which of course I don't want since I want to require DI.
Here's the Ninject class I created:
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();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new Ninject.WebApi.DependencyResolver.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.Load(Assembly.GetExecutingAssembly());
kernel.Bind<IUnitsSL>().To<UnitsSL>();
kernel.Bind<IForecastLogic>().To<ForecastLogic>();
kernel.Bind<IForecastRepositoryAsync>().To<ForecastRepositoryAsync>();
}
}
Here is the controller
namespace ForecastApi.Controllers
{
public class ForecastController : ApiController
{
private IUnitsSL _serviceLayer { get; set; }
private readonly IForecastLogic _forecastLogic;
public ForecastController(IForecastLogic forecastLogic)
{
_forecastLogic = forecastLogic;
_serviceLayer = new UnitsSL();
}
[Route("projection")]
[HttpPost]
public async Task<IHttpActionResult> GetDemandForecast([FromBody]
ProjectionRequestModel model)
{
var retVal = await _forecastLogic.GetDemandForecastData(model);
return Ok(retVal);
}
}
The exact wording of the error message when I test this through Postman is: An error occurred when trying to create a controller of type 'ForecastController'. Make sure that the controller has a parameterless public constructor."
If it helps, I am mocking my unit tests for the business calls and they are working with the Ninject library and Moq. It is the constructor that seems to fail.
TIA
For whatever reason, uninstalling Ninject entirely and reinstalling it (this is version 3.3) solved the problem. Leaving this here in the event that anyone else has a similar issue. I had originally installed
Ninject
Ninject.Web.Common
Ninject.Web.Common.WebHost
Ninject.Web.WebApi
Ninject.Web.WebApi.WebHost
When I uninstalled all of these packages, then re-installed them v3.3 again, the NinjectWebCommon.cs file was added and all worked ok. I can only assume that there was something missing when I rolled my own common file to make up for Ninject not installing it the first go around.
Related
SO I had a perfectly working WebApi service with Unity. I decided to take Nuget package update which overwrote the UnityConfig.cs, However, i added my code back and it works all fine when I try to run it from VisualStudio. Problem is when i deploy the bin and try to run the api from IIS. I get a 500, with following exception :
Exception.Source = System.Web.Http.Dispatcher.DefaultHttpControllerActivator
Exception.Message = An error occurred when trying to create a controller of type 'StateController'. Make sure that the controller has a parameterless public constructor.
/// <summary>
/// Specifies the Unity configuration for the main container.
/// </summary>
public static class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
/// <summary>
/// Configured Unity Container.
/// </summary>
public static IUnityContainer Container => container.Value;
#endregion
public static void RegisterTypes(IUnityContainer container)
{
string dbConnectionString = WebConfigurationManager.ConnectionStrings["abc"].ConnectionString;
StateRepository stateRepository = new StateRepository(dbConnectionString);
// Register a default (un-named) type mapping with a singleton lifetime
container.RegisterInstance<IStateRepository>(stateRepository);
}
}
Hers is my UnityWebApiActivator.cs
using System.Web.Http;
using Unity.AspNet.WebApi;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(PowerManagementServices.UnityWebApiActivator), nameof(PowerManagementServices.UnityWebApiActivator.Start))]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(PowerManagementServices.UnityWebApiActivator), nameof(PowerManagementServices.UnityWebApiActivator.Shutdown))]
namespace PowerManagementServices
{
/// <summary>
/// Provides the bootstrapping for integrating Unity with WebApi when it is hosted in ASP.NET.
/// </summary>
public static class UnityWebApiActivator
{
/// <summary>
/// Integrates Unity when the application starts.
/// </summary>
public static void Start()
{
// Use UnityHierarchicalDependencyResolver if you want to use
// a new child container for each IHttpController resolution.
// var resolver = new UnityHierarchicalDependencyResolver(UnityConfig.Container);
var resolver = new UnityDependencyResolver(UnityConfig.Container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
/// <summary>
/// Disposes the Unity container when the application is shut down.
/// </summary>
public static void Shutdown()
{
UnityConfig.Container.Dispose();
}
}
}
what is missing ? As I mentioned this service was working perfectly before I took the nuget update. Now it works from VS but not when deployed.
Thanks In Advance.
I am trying to learn MVC and I started out with the book Pro ASP.NET MVC by Adam Freeman (5th edition #2013).
In chapter VII I'm trying to follow the example in the book making a small app.
The app fails to load after setting it up and trying to load a list of products.
I'm trying to create a mock implementation of the abstract repository IProductRepository and have Ninject return the mock object whenever it gets a request for an implementation of the IProductRepository interface.
I've searched and looked over other questions/ answers and found nothing that could help solve my problem and let me move forward with studying. This may be basic stuff but I really want to know what and why is not working as it should.
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();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(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)
{
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}
}
}
This next is my NinjectDependencyResolver class:
public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernel;
[Inject]
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
var mock = new Mock<IProductsRepository>();
mock.Setup(m => m.Products).Returns(new List<Product>
{
new Product { Name = "Fotball", Price = 25 },
new Product { Name = "Surf Board", Price = 45 },
new Product { Name = "Running Shoes", Price = 95 }
});
kernel.Bind<IProductsRepository>().ToConstant(mock.Object);
}
}
And this is my controller class:
public class ProductController : Controller
{
private IProductsRepository repository;
public ProductController(IProductsRepository productRepository)
{
repository = productRepository;
}
public ViewResult List()
{
return View(repository.Products);
}
The error I get is the following:
Error activating IProductsRepository
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IProductsRepository into parameter productRepository of constructor of type ProductController.
1) Request for ProductController.
Suggestions:
1) Ensure that you have defined a binding for IProductsRepository.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
OK, so it seems that I had another error which said:
Found conflicts between different versions of the same dependent assembly that could not be resolved
I had installed the specific versions of Ninject, Ninject.Web.Common, Ninject.MVC3, Moq and the other packages as specified by the book author.
After reading the error in the build output I tried updating all installed packages to the latest versions, rebuild the project and it all worked just fine!
I'm using NinjectWebCommon to perform the injections in my controllers. I installed the package via Nuget and he created the NinjectWebCommon.cs in my App_Start as it says in the own documentation. I need to know why it does not work as it should, because I follow the documentation step by step. Follows some snippets:
NinjectWebCommon.cs:
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.Load(AppDomain.CurrentDomain.GetAssemblies());
kernel.Bind<IFooService>().To<FooService>();
}
}
Controller:
public class FooController : Controller
{
private readonly IFooService fooService;
public FooController(IFooService fooService)
{
this.fooService = fooService;
}
public ActionResult Index()
{
return View(this.fooService.All());
}
}
This generates this error:
Error activating IFooService No matching bindings are available, and
the type is not self-bindable. Activation path:
2) Injection of
dependency IFooService into parameter fooService of constructor of
type FooController
1) Request for FooController
Suggestions:
1) Ensure that you have defined a binding for
IFooService.
2) If the binding was defined in a module, ensure that
the module has been loaded into the kernel.
3) Ensure you have not
accidentally created more than one kernel.
4) If you are using
constructor arguments, ensure that the parameter name matches the
constructors parameter name.
5) If you are using automatic module
loading, ensure the search path and filters are correct.
Use IoC to resolve instances, but it works only in my HomeController, if I change to another controller using EXACTLY the same code (with the IoC), it generates the error again. Follows the code using the IoC.
using IoC:
private readonly IFooService fooService;
public HomeController()
{
this.fooService = IoC.Instance.Resolve<IFooService>();
}
public ActionResult Index()
{
ViewBag.MyFoos = this.fooService.All();
return View();
}
generates this error:
No matching bindings are available, and the type is not self-bindable.
Error activating IFooService
No matching bindings are available,
and the type is not self-bindable.
Activation path:
1) Request for IFooService
Suggestions:
1) Ensure
that you have defined a binding for IFooService.
2) If the binding
was defined in a module, ensure that the module has been loaded into
the kernel.
3) Ensure you have not accidentally created more than one
kernel.
4) If you are using constructor arguments, ensure that the
parameter name matches the constructors parameter name.
5) If you are
using automatic module loading, ensure the search path and filters are
correct.
Are you sure you have a binding for ISetorService? I don't see one in the code you've posted.
I solved the problem by loading all "NinjectModule" of my application hierarchy.
I thought it was sufficient loading only the main module, then created another statico method within the "NinjectWebCommon" just to separate responsibilities and organizing the code. Below is the code used:
var kernel = new StandardKernel(new Repository(), new Service(), new ValidationAndBusinessRules());
which carry all their Repositories, Services and Validators in creating the Kernel.
private static void RegisterObrigatoryServices(IKernel kernel)
{
kernel.Bind<IIdentityProvider>().To<ServiceIdentityProvider>();
kernel.Bind<Guid>().ToMethod(ctx => default(Guid)).Named("CurrentProcessId");
kernel.Bind<ISession>().ToMethod(ctx =>
{
SessionPoolManager.Update();
Guid processId = kernel.Get<Guid>("CurrentProcessId", new Parameter[] { });
if (processId == default(Guid))
{
return SessionFactoryBuilder.SessionFactory(kernel.Get<IIdentityProvider>()).OpenSession();
}
else
{
ISession session = SessionPoolManager.Get(processId);
if (session == null)
{
session = SessionFactoryBuilder.SessionFactory(kernel.Get<IIdentityProvider>()).OpenSession();
SessionPoolManager.Register(processId, session);
}
return session;
}
});
}
method created by me within the NinjectWebCommon as mentioned above, only to record the required dependencies.
All this code is basically native and has been inserted into the Nuget Ninject.MVC4 package (installed via Package Manager Console within Visual Studio). This package inserts a class in App_Start directory called "NinjectWebCommon," and it is that I made these changes.
the controler is set to send the package documentation, as follows:
public class HomeController : Controller
{
private readonly IFooService fooService;
public HomeController(IFooService fooService)
{
this.fooService = fooService; //Daqui para frente é possível usar normalmente o service.
}
}
I have no idea what is going on with this. It makes no sense to me.
I have a controller that throws the following error:
System.InvalidOperationException: An error occurred when trying to create a controller of type 'LandingController'. Make sure that the controller has a parameterless public constructor. ---> Ninject.ActivationException: Error activating IApiService using binding from IApiService to ApiService No constructor was available to create an instance of the implementation type. Activation path: 2) Injection of dependency IApiService into parameter apiService of constructor of type LandingController 1) Request for LandingController Suggestions: 1) Ensure that the implementation type has a public constructor. 2) If you have implemented the Singleton pattern, use a binding with InSingletonScope() instead.
No matter what I do nothing works.
If I have:
no constructors in the controller
one constructor with the service
two constructors with the service and parameterless
If I hope for the parameterless constructor to work, then it does not resolve the IApiService.
I have the following setup in NinjectWebCommon:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IApiService>().To<ApiService>();
kernel.Bind<IMembersClient>().To<MembersClient>();
}
Controller is:
public class LandingController : Controller
{
IApiService _apiService;
LandingController(IApiService apiService)
{
_apiService = apiService;
}
// GET: Landing
public ActionResult Index()
{
var avm = new ApplicationViewModel();
_apiService.GetAcc();
return View(avm);
}
}
API Service is:
public class ApiService : IApiService
{
private readonly IMembersClient _membersClient;
ApiService(IMembersClient membersClient)
{
_membersClient = membersClient;
}
public void GetAcc()
{
_membersClient.Test();
}
}
Member Client is:
public class MembersClient : IMembersClient
{
public MembersClient()
{
public void Test()
{
}
}
}
This was the best post I found:
Ninject Dependency Injection with Asp.Net MVC3 or MVC4
But it never helped solve the issue.
EDIT: Full NinjectWebCommon
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<IApiService>().To<ApiService>();
kernel.Bind<IMembersClient>().To<MembersClient>();
}
EDIT : Trying Property Injection
Code for property injection:
[Inject]
public IApiService ApiServiceC { private get; set; }
Updated Error:
System.InvalidOperationException: An error occurred when trying to create a controller of type 'LandingController'. Make sure that the controller has a parameterless public constructor. ---> Ninject.ActivationException: Error activating IApiService using binding from IApiService to ApiService No constructor was available to create an instance of the implementation type. Activation path: 2) Injection of dependency IApiService into property ApiServiceC of type LandingController 1) Request for LandingController Suggestions: 1) Ensure that the implementation type has a public constructor. 2) If you have implemented the Singleton pattern, use a binding with InSingletonScope() instead.
Well.... after much testing and trying different things.
The solution was to delete IApiService and ApiService completely and recreate them.
That successfully made everything wire up correctly again.
I'm trying to use the new ASP.Net MVC 4 Web API project template with Ninject but have hit a wall on the following error:
Method 'GetFilters' in type 'Ninject.Web.WebApi.Filter.DefaultFilterProvider' from assembly 'Ninject.Web.WebApi, Version=3.0.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7' does not have an implementation.
I am creating a brand new project in Visual Studio 2010 using the ASP.Net MVC 4 -> Web API template and I am using the latest Ninject NuGet packages:
Ninject 3.0.1.10
Ninject.Web.Common 3.0.0.7
Ninject.Web.WebApi 3.0.0.2
I have attempted the solution presented in this question however I've not had any luck - if I remove the reference to Ninject.Web.WebApi then MVC never engages Ninject. I also notice they mention Ninject.MVC3 however I am using the new Ninject.WebApi plugin.
I am using the default binding code in NinjectWebCommon.cs that is created during the NuGet install and attempting to register one simple service in RegisterServices()
[assembly: WebActivator.PreApplicationStartMethod(typeof(mkts.web.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(mkts.web.App_Start.NinjectWebCommon), "Stop")]
namespace mkts.web.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using mkts.service;
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();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(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)
{
//Test binding
kernel.Bind<IStudentService>().To<StudentService>();
}
}
}
My controller:
namespace mkts.web.Controllers
{
public class HomeController : Controller
{
private readonly IStudentService studentService;
public HomeController(IStudentService studentService)
{
this.studentService = studentService;
}
public ActionResult Index()
{
return View();
}
}
}
Many thanks in advance for any help with this.
Ninject.WebApi was written against the Beta and is deprecated now.
Remove that, install Ninject.MVC3.
Now you will need a homebrewed IDependencyResolver and IDependencyScope. I posted a walkthrough here - http://www.strathweb.com/2012/05/using-ninject-with-the-latest-asp-net-web-api-source/