I need to use Ninject on a Web APi app (I created it using the empty web api template).
I installed the following nuget package :
Ninject.Web.WebApi
Ninject.MVC3
Here is my application_start
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
My Ninject.Web.Common
[assembly: WebActivator.PreApplicationStartMethod(typeof(rb.rpg.backend.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(rb.rpg.backend.App_Start.NinjectWebCommon), "Stop")]
namespace rb.rpg.backend.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using Raven.Client;
using RemiDDD.Framework.Cqrs;
using System.Web.Http.Dependencies;
using System.Web.Http;
using System.Collections.Generic;
using Ninject.Web.WebApi;
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.Mvc.DependencyResolver.SetResolver(new LocalNinjectDependencyResolver(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<IDocumentSession>()
.ToMethod(ctx => WebApiApplication.DocumentStore.OpenSession())
.InRequestScope();
kernel.Bind<MessageProcessor>()
.ToMethod(ctx =>
{
var MessageProcessor = new MessageProcessor(kernel);
/*...*/
return MessageProcessor;
})
.InSingletonScope();
}
}
}
When I rebuild the app the first loading is fine, my contrller gets my IDocumentSession. But when I reload the same page, I got the errror
"the type .. has no default constructor"
Here is how I set it up in my Web API projects:
Download regular Ninject from nuget.org
PM> Install-Package Ninject
In your Web API project add new folder named Infrastructure in that folder create 2 files:
NInjectDependencyScope.cs with content:
public class NInjectDependencyScope : IDependencyScope
{
private IResolutionRoot _resolutionRoot;
public NInjectDependencyScope(IResolutionRoot resolutionRoot)
{
_resolutionRoot = resolutionRoot;
}
public void Dispose()
{
var disposable = _resolutionRoot as IDisposable;
if (disposable != null)
disposable.Dispose();
_resolutionRoot = null;
}
public object GetService(Type serviceType)
{
return GetServices(serviceType).FirstOrDefault();
}
public IEnumerable<object> GetServices(Type serviceType)
{
var request = _resolutionRoot.CreateRequest(serviceType, null, new IParameter[0], true, true);
return _resolutionRoot.Resolve(request);
}
}
and NInjectDependencyResolver.cs with content:
public class NInjectDependencyResolver : NInjectDependencyScope, IDependencyResolver
{
private IKernel _kernel;
public NInjectDependencyResolver(IKernel kernel) : base(kernel)
{
_kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NInjectDependencyScope(_kernel.BeginBlock());
}
}
In Global.asax file in Application_Start() method add:
//Ninject dependency injection configuration
var kernel = new StandardKernel();
kernel.Bind<IXyzRepository>().To<EFXyzRepository>();
GlobalConfiguration.Configuration.DependencyResolver = new NInjectDependencyResolver(kernel);
so that your final Global.asax file will look like this:
public class XyzApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//Ninject dependency injection configuration
var kernel = new StandardKernel();
//Your dependency bindings
kernel.Bind<IXyzRepository>().To<EFXyzRepository>();
GlobalConfiguration.Configuration.DependencyResolver = new NInjectDependencyResolver(kernel);
}
}
An that is it!
Here is the example of usage:
public class PersonController : ApiController
{
private readonly IXyzRepository repository;
public PersonController(IXyzRepository repo)
{
repository = repo;
}
...
...
...
I hope this helps.
Related
Hello all I've Added Unity to an MVC app. it seems that DI is working with the MVC Portion of the app but i cannot figure out why it wont work with the API part of the application.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name:"DefaultApi",
routeTemplate:"api/{controller}/{id}",
defaults: new {id = RouteParameter.Optional}
);
config.Formatters.Add(new JsonMediaTypeFormatter());
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.None;
}
}
public static class UnityMvcActivator
{
/// <summary>
/// Integrates Unity when the application starts.
/// </summary>
public static void Start(HttpConfiguration configuration)
{
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(UnityConfig.Container));
DependencyResolver.SetResolver(new UnityDependencyResolver(UnityConfig.Container));
// TODO: Uncomment if you want to use PerRequestLifetimeManager
// Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
/// <summary>
/// Disposes the Unity container when the application is shut down.
/// </summary>
public static void Shutdown()
{
UnityConfig.Container.Dispose();
}
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Address", action = "Index", id = UrlParameter.Optional }
);
}
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
BundleConfig.RegisterBundles(BundleTable.Bundles);
RouteConfig.RegisterRoutes(RouteTable.Routes);
UnityMvcActivator.Start(GlobalConfiguration.Configuration);
}
I am just trying to get a repository to work in the web api but i keep getting
An error occurred when trying to create a controller of type 'AddressSearchController'. Make sure that the controller has a parameterless public constructor.",
this error. I have seen a few posts about this. I have tried them and still cannot get this to work. Does anyone have any suggestions?
public class AddressSearchController:_SimpleController<Address>
{
public AddressSearchController(IRepository<Address> addressRepository) : base(addressRepository)
{
}
[HttpPost]
[Route("api/AddressSearch/Search")]
public IHttpActionResult Search([FromBody] AddressSearchDto addressSearchDto)
{
var addresses = new List<Address>()
{
CreateAddress(1,"Main St", 123),
CreateAddress(2,"Main St", 124),
CreateAddress(3,"Main St", 125),
};
return Ok(addresses);
}
static Address CreateAddress(int id,string street, int houseNumber)
{
return new Address()
{
Id = id,
StreetName = street,
HouseNumber = houseNumber
};
}
}
public static void RegisterTypes(IUnityContainer container)
{
RegisterInstances(container);
}
private static void RegisterInstances(IUnityContainer container)
{
container.RegisterType<IAddressContext, AddressContext>();
container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
}
using System;
using Address_Tracker.Data.Context;
using Address_Tracker.Data.Context.Interfaces;
using Address_Tracker.Data.Repositories;
using Unity;
namespace Address_Tracker
{
/// <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
/// <summary>
/// Registers the type mappings with the Unity container.
/// </summary>
/// <param name="container">The unity container to configure.</param>
/// <remarks>
/// There is no need to register concrete types such as controllers or
/// API controllers (unless you want to change the defaults), as Unity
/// allows resolving a concrete type even if it was not previously
/// registered.
/// </remarks>
public static void RegisterTypes(IUnityContainer container)
{
RegisterInstances(container);
}
private static void RegisterInstances(IUnityContainer container)
{
container.RegisterType<IAddressContext, AddressContext>();
container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
}
}
}
Your AddressSearchController should have a default constructor, or if you have no default / parameterless constructor, then please pass interfaces instead of concrete classes in AddressSearchController.
I believe you may have such a scenario:
public class AddressSearchController : ApiController
{
public AddressSearchController(SomeClassParameter obj)
{
//some code
}
}
What you want actually is ether this:
public class AddressSearchController : ApiController
{
public AddressSearchController() // add default ctor
{
}
public AddressSearchController(SomeClassParameter obj)
{
//some code
}
}
or this:
Register the interface ISomeClassParameter for type SomeClassParameter in Unity
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
UnityConfig.RegisterComponents(); // <----- Add this line
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Register component:
container.RegisterType<ISomeClassParameter , SomeClassParameter >();
and do constructor injection :
public class AddressSearchController : ApiController
{
public AddressSearchController(ISomeClassParameter obj)
{
//some code
}
}
Also, make sure you have the WebApi version of Unity
I tried it out, it worked for me:
I'm having compilation error when calling my service in global.asax. Im using UnityMvc as my DI. It was working when called in my controllers but no in Global.asax. Here is the error.
Compiler Error Message: CS7036: There is no argument given that corresponds to the required formal parameter 'genreService' of 'MvcApplication.MvcApplication(IGenreService)'
Global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
private readonly IGenreService _genreService;
public MvcApplication(IGenreService genreService)
{
_genreService = genreService;
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
GenreService.cs
public partial class GenreService : IGenreService
{
private readonly IRepository<Genre> _genreRepository;
private readonly IRepository<GameGenre> _gameGenreRepository;
public GenreService(IRepository<Genre> genreRepository, IRepository<GameGenre> gameGenreRepository)
{
_genreRepository = genreRepository;
_gameGenreRepository = gameGenreRepository;
}
// methods
}
IGenreService.cs
public partial interface IGenreService
{
// interface
}
UnityConfig.cs
using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Data.Entity;
using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
using GameCommerce.Infrastructure.Services.GameLibrary;
using GameCommerce.Infrastructure;
using Microsoft.AspNet.Identity.EntityFramework;
using GameCommerce.Infrastructure.ApplicationUsers;
using System.Web;
using GameCommerce.Infrastructure.Services.Message;
namespace GameCommerce.Web.App_Start
{
/// <summary>
/// Specifies the Unity configuration for the main container.
/// </summary>
public class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
/// <summary>
/// Gets the configured Unity container.
/// </summary>
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
#endregion
/// <summary>Registers the type mappings with the Unity container.</summary>
/// <param name="container">The unity container to configure.</param>
/// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to
/// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();
// TODO: Register your types here
// container.RegisterType<IProductRepository, ProductRepository>();
container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager());
container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new InjectionConstructor(new ApplicationDbContext()));
container.RegisterType<Areas.Admin.Controllers.AccountController>(new InjectionConstructor());
container.RegisterType<Controllers.AccountController>(new InjectionConstructor());
container.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication));
container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
container.RegisterType<IGameService, GameService>();
container.RegisterType<IGenreService, GenreService>();
container.RegisterType<IGameDeveloperService, GameDeveloperService>();
container.RegisterType<IGamePublisherService, GamePublisherService>();
container.RegisterType<IMessageService, MessageService>();
}
}
}
Try with the below code:
using Microsoft.Practices.Unity;
public class MvcApplication : System.Web.HttpApplication
{
private readonly IGenreService _genreService;
public MvcApplication()
{
_genreService = GameCommerce.Web.App_Start.UnityConfig.GetConfiguredContainer().Resolve<IGenreService>();
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
DepedencyResolver in MVC by default is used for resolution in controllers, so here we are using explicity using the Container for resolution in 'MvcApplication'.
Here is the issue at hand:
While calling my CustomerController through the URL, I get the following exception:
ExceptionMessage:
An error occurred when trying to create a controller of type
'CustomerController'. Make sure that the controller has a
parameterless public constructor.
I am using the following url's:
http://localhost:55555/api/Customer/
http://localhost:55555/api/Customer/8
Please note: The /api/Customer/ call were working before I refactored the logic into a business class and implemented dependency injection.
My research suggests that I am not registering my interface and class correctly with Ninject, but not sure what step I am missing.
Researched Links:
Make sure that the controller has a parameterless public constructor error
Make sure that the controller has a parameterless public constructor in Unity
Here is my question What is causing this exception? I am registering my interface/class within Ninject, but it doesn't seem to recognize the mapping correctly. Any thoughts?
Customer Controller
public class CustomerController : ApiController
{
private readonly ICustomerBusiness _customerBusiness;
public CustomerController(ICustomerBusiness customerBusiness)
{
_customerBusiness = customerBusiness;
}
// GET api/Customer
[HttpGet]
public IEnumerable<Customer> GetCustomers()
{
return _customerBusiness.GetCustomers();
}
// GET api/Customer/Id
[HttpGet]
public IEnumerable<Customer> GetCustomersById(int customerId)
{
return _customerBusiness.GetCustomerById(customerId);
}
}
Customer Business
public class CustomerBusiness : ICustomerBusiness
{
private readonly DatabaseContext _databaseContext = new DatabaseContext();
public IEnumerable<Customer> GetCustomers()
{
return _databaseContext.Customers;
}
public IQueryable<Customer> GetCustomerById(int customerId)
{
return _databaseContext.Customers.Where(c => c.CustomerId == customerId);
}
}
Customer Business Interface
public interface ICustomerBusiness
{
IQueryable<Customer> GetCustomerById(int customerId);
IEnumerable<Customer> GetCustomers();
}
NinjectWebCommon
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using MyReservation.API;
using MyReservation.API.Business;
using Ninject;
using Ninject.Web.Common;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(NinjectWebCommon), "Stop")]
namespace MyReservation.API
{
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<ICustomerBusiness>().To<CustomerBusiness>();
}
}
}
For the same problem I installed the nuget packages
ninject
ninject.web.common
ninject.web.common.webhost
ninject.web.webapi
ninject.web.webapi.webhost
and worked
I have a problem to use web api Owin with ninject. When I try to use my web api , it was this error, and I can not fix this problem , I've tried many ways , none of which revolved my problem.
This error occurs when I boot my application
Error activating ModelValidatorProvider using binding from ModelValidatorProvider to
NinjectDefaultModelValidatorProvider
A cyclical dependency was detected between the constructors of two services.
Activation path:
3) Injection of dependency ModelValidatorProvider into parameter defaultModelValidatorProviders of constructor of type DefaultModelValidatorProviders
2) Injection of dependency DefaultModelValidatorProviders into parameter defaultModelValidatorProviders of constructor of type NinjectDefaultModelValidatorProvider
1) Request for ModelValidatorProvider
Suggestions:
1) Ensure that you have not declared a dependency for ModelValidatorProvider on any implementations of the service.
2) Consider combining the services into a single one to remove the cycle.
3) Use property injection instead of constructor injection, and implement IInitializable
if you need initialization logic to be run after property values have been injected
My statup.cs
var config = new HttpConfiguration();
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/api/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(365),
Provider = new SimpleAuthorizationServerProvider(),
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
config.DependencyResolver = new NinjectResolver(NinjectWebCommon.CreateKernel());
app.UseWebApi(config);
My class DependencyResolver.cs
public class NinjectDependencyScope : IDependencyScope, System.Web.Mvc.IDependencyResolver
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
Contract.Assert(resolver != null);
this.resolver = resolver;
}
public void 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 NinjectResolver : NinjectDependencyScope, System.Web.Mvc.IDependencyResolver, IDependencyResolver
{
private IKernel kernel;
public NinjectResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel);
}
}
and my class 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>
public 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)
{
//Injeções de Depêndencias
//Inject AppService
kernel.Bind(typeof (IAppServiceBase<>)).To(typeof (AppServiceBase<>));
kernel.Bind<ICanalDistribuicaoAppService>().To<CanalDistribuicaoAppService>();
kernel.Bind<ICaracteristicasAppService>().To<CaracteristicasAppService>();
kernel.Bind<ICaracteristicasValorAppService>().To<CaracteristicasValorAppService>();
kernel.Bind<ICentroAppService>().To<CentroAppService>();
kernel.Bind<IClassificacaoContabilAppService>().To<ClassificacaoContabilAppService>();
kernel.Bind<IClienteAppService>().To<ClienteAppService>();
kernel.Bind<IClienteModalidadeCentroAppService>().To<ClienteModalidadeCentroAppService>();
kernel.Bind<IClienteTipoCarregamentoCentroAppService>().To<ClienteTipoCarregamentoCentroAppService>();
kernel.Bind<IClienteEmailAppService>().To<ClienteEmailAppService>();
kernel.Bind<IClienteGrupoAppService>().To<ClienteGrupoAppService>();
kernel.Bind<IClienteStatusAppService>().To<ClienteStatusAppService>();
kernel.Bind<ICondicaoPagamentoAppService>().To<CondicaoPagamentoAppService>();
kernel.Bind<IDimensoesAppService>().To<DimensoesAppService>();
kernel.Bind<IEmbalagemAppService>().To<EmbalagemAppService>();
kernel.Bind<IEscritorioVendasAppService>().To<EscritorioVendasAppService>();
kernel.Bind<IEstoqueAppService>().To<EstoqueAppService>();
kernel.Bind<IGrupoProdutoRestritoAppService>().To<GrupoProdutoRestritoAppService>();
kernel.Bind<ILiberacaoCIFAppService>().To<LiberacaoCIFAppService>();
kernel.Bind<ILocalRetiradaAppService>().To<LocalRetiradaAppService>();
kernel.Bind<IMateriaisAppService>().To<MateriaisAppService>();
kernel.Bind<IModalidadeAppService>().To<ModalidadeAppService>();
kernel.Bind<IOrganizacaoVendasAppService>().To<OrganizacaoVendasAppService>();
kernel.Bind<IPedidoFavoritoAppService>().To<PedidoFavoritoAppService>();
kernel.Bind<IProdutoAppService>().To<ProdutoAppService>();
kernel.Bind<IRamoEmpresaAppService>().To<RamoEmpresaAppService>();
kernel.Bind<ISegmentoMercadoAppService>().To<SegmentoMercadoAppService>();
kernel.Bind<ISetorAtividadeAppService>().To<SetorAtividadeAppService>();
kernel.Bind<IStatusReservaAppService>().To<StatusReservaAppService>();
kernel.Bind<ISubstituicaoFiscalAppService>().To<SubstituicaoFiscalAppService>();
kernel.Bind<ITipoCarregamentoAppService>().To<TipoCarregamentoAppService>();
kernel.Bind<ITipoEmailAppService>().To<TipoEmailAppService>();
kernel.Bind<IUtilizacaoAppService>().To<UtilizacaoAppService>();
kernel.Bind<IUsuarioAppService>().To<UsuarioAppService>();
//Inject Services
kernel.Bind(typeof (IServiceBase<>)).To(typeof (ServiceBase<>));
kernel.Bind<ICanalDistribuicaoService>().To<CanalDistribuicaoService>();
kernel.Bind<ICaracteristicasService>().To<CaracteristicasService>();
kernel.Bind<ICaracteristicasValorService>().To<CaracteristicasValorService>();
kernel.Bind<ICentroService>().To<CentroService>();
kernel.Bind<IClassificacaoContabilService>().To<ClassificacaoContabilService>();
kernel.Bind<IClienteService>().To<ClienteService>();
kernel.Bind<IClienteModalidadeCentroService>().To<ClienteModalidadeCentroService>();
kernel.Bind<IClienteTipoCarregamentoCentroService>().To<ClienteTipoCarregamentoCentroService>();
kernel.Bind<IClienteEmailService>().To<ClienteEmailService>();
kernel.Bind<IClienteGrupoService>().To<ClienteGrupoService>();
kernel.Bind<IClienteStatusService>().To<ClienteStatusService>();
kernel.Bind<ICondicaoPagamentoService>().To<CondicaoPagamentoService>();
kernel.Bind<IDimensoesService>().To<DimensoesService>();
kernel.Bind<IEmbalagemService>().To<EmbalagemService>();
kernel.Bind<IEscritorioVendasService>().To<EscritorioVendasService>();
kernel.Bind<IEstoqueService>().To<EstoqueService>();
kernel.Bind<IGrupoProdutoRestritoService>().To<GrupoProdutoRestritoService>();
kernel.Bind<ILiberacaoCIFService>().To<LiberacaoCIFService>();
kernel.Bind<ILocalRetiradaService>().To<LocalRetiradaService>();
kernel.Bind<IMateriaisService>().To<MateriaisService>();
kernel.Bind<IModalidadeService>().To<ModalidadeService>();
kernel.Bind<IOrganizacaoVendasService>().To<OrganizacaoVendasService>();
kernel.Bind<IPedidoFavoritoService>().To<PedidoFavoritoService>();
kernel.Bind<IProdutoService>().To<ProdutoService>();
kernel.Bind<IRamoEmpresaService>().To<RamoEmpresaService>();
kernel.Bind<ISegmentoMercadoService>().To<SegmentoMercadoService>();
kernel.Bind<ISetorAtividadeService>().To<SetorAtividadeService>();
kernel.Bind<IStatusReservaService>().To<StatusReservaService>();
kernel.Bind<ISubstituicaoFiscalService>().To<SubstituicaoFiscalService>();
kernel.Bind<ITipoCarregamentoService>().To<TipoCarregamentoService>();
kernel.Bind<ITipoEmailService>().To<TipoEmailService>();
kernel.Bind<IUtilizacaoService>().To<UtilizacaoService>();
kernel.Bind<IUsuarioService>().To<UsuarioService>();
//Inject Repositories
kernel.Bind(typeof (IRepositoryBase<>)).To(typeof (RepositoryBase<>));
kernel.Bind<ICanalDistribuicaoRepository>().To<CanalDistribuicaoRepository>();
kernel.Bind<ICaracteristicasRepository>().To<CaracteristicasRepository>();
kernel.Bind<ICaracteristicasValorRepository>().To<CaracteristicasValorRepository>();
kernel.Bind<ICentroRepository>().To<CentroRepository>();
kernel.Bind<IClassificacaoContabilRepository>().To<ClassificacaoContabilRepository>();
kernel.Bind<IClienteRepository>().To<ClienteRepository>();
kernel.Bind<IClienteModalidadeCentroRepository>().To<ClienteModalidadeCentroRepository>();
kernel.Bind<IClienteTipoCarregamentoCentroRepository>().To<ClienteTipoCarregamentoCentroRepository>();
kernel.Bind<IClienteEmailRepository>().To<ClienteEmailRepository>();
kernel.Bind<IClienteGrupoRepository>().To<ClienteGrupoRepository>();
kernel.Bind<IClienteStatusRepository>().To<ClienteStatusRepository>();
kernel.Bind<ICondicaoPagamentoRepository>().To<CondicaoPagamentoRepository>();
kernel.Bind<IDimensoesRepository>().To<DimensoesRepository>();
kernel.Bind<IEmbalagemRepository>().To<EmbalagemRepository>();
kernel.Bind<IEscritorioVendasRepository>().To<EscritorioVendasRepository>();
kernel.Bind<IEstoqueRepository>().To<EstoqueRepository>();
kernel.Bind<IGrupoProdutoRestritoRepository>().To<GrupoProdutoRestritoRepository>();
kernel.Bind<ILiberacaoCIFRepository>().To<LiberacaoCIFRepository>();
kernel.Bind<ILocalRetiradaRepository>().To<LocalRetiradaRepository>();
kernel.Bind<IMateriaisRepository>().To<MateriaisRepository>();
kernel.Bind<IModalidadeRepository>().To<ModalidadeRepository>();
kernel.Bind<IOrganizacaoVendasRepository>().To<OrganizacaoVendasRepository>();
kernel.Bind<IPedidoFavoritoRepository>().To<PedidoFavoritoRepository>();
kernel.Bind<IProdutoRepository>().To<ProdutoRepository>();
kernel.Bind<IRamoEmpresaRepository>().To<RamoEmpresaRepository>();
kernel.Bind<ISegmentoMercadoRepository>().To<SegmentoMercadoRepository>();
kernel.Bind<ISetorAtividadeRepository>().To<SetorAtividadeRepository>();
kernel.Bind<IStatusReservaRepository>().To<StatusReservaRepository>();
kernel.Bind<ISubstituicaoFiscalRepository>().To<SubstituicaoFiscalRepository>();
kernel.Bind<ITipoCarregamentoRepository>().To<TipoCarregamentoRepository>();
kernel.Bind<ITipoEmailRepository>().To<TipoEmailRepository>();
kernel.Bind<IUtilizacaoRepository>().To<UtilizacaoRepository>();
kernel.Bind<IUsuarioRepository>().To<UsuarioRepository>();
}
}
Help me plis.
I know its very old Q but still comes up in google in top 3 search for this error. So as a solution just remove ninject.web.webapi and its dependencies like ninject.web.webapi.webhost.
Before I set up the question you should know that I got my current code from this page:
http://www.strathweb.com/2012/05/using-ninject-with-the-latest-asp-net-web-api-source/
I'm trying to use ASP.NET Web API and Ninject in my application by using an IDependencyResolver adapter found on the site above.
I created all the code just like it shows on the site and it works but when I load up my appication my regular controllers fail and show this error:
[MissingMethodException: No parameterless constructor defined for this object.]
[InvalidOperationException: An error occurred when trying to create a controller of type 'AccountManager.Controllers.HomeController'...
So, it seems like I can use Ninject with regular controllers or Web API controllers but not both. :(
Here is my code:
NinjectResolver.cs
public class NinjectResolver : NinjectScope, IDependencyResolver
{
private IKernel _kernel;
public NinjectResolver(IKernel kernel)
: base(kernel)
{
_kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectScope(_kernel.BeginBlock());
}
}
NinjectScope.cs
public class NinjectScope : IDependencyScope
{
protected IResolutionRoot resolutionRoot;
public NinjectScope(IResolutionRoot kernel)
{
resolutionRoot = kernel;
}
public object GetService(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).SingleOrDefault();
}
public IEnumerable<object> GetServices(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).ToList();
}
public void Dispose()
{
IDisposable disposable = (IDisposable)resolutionRoot;
if (disposable != null) disposable.Dispose();
resolutionRoot = null;
}
}
Global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
private void SetupDependencyInjection()
{
//create Ninject DI Kernel
IKernel kernel = new StandardKernel();
//register services with Ninject DI container
RegisterServices(kernel);
//tell asp.net mvc to use our Ninject DI Container
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
}
}
AccountingController.cs
public class AccountingController : ApiController
{
private ICustomerService _customerService;
public AccountingController(ICustomerService service)
{
_customerService = service;
}
// GET /api/<controller>/5
public string Get(int id)
{
return "value";
}
}
Insert the following line of code into the CreateKernel() method before the call to the RegisterServices(kernel); is made.
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
You will also need to use the below code, I prefer to have it defined in the same class.
public class NinjectResolver : NinjectScope, IDependencyResolver
{
private IKernel _kernel;
public NinjectResolver(IKernel kernel) : base(kernel)
{
_kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectScope(_kernel.BeginBlock());
}
}
public class NinjectScope : IDependencyScope
{
protected IResolutionRoot resolutionRoot;
public NinjectScope(IResolutionRoot kernel)
{
resolutionRoot = kernel;
}
public object GetService(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).SingleOrDefault();
}
public IEnumerable<object> GetServices(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).ToList();
}
public void Dispose()
{
IDisposable disposable = (IDisposable)resolutionRoot;
if (disposable != null) disposable.Dispose();
resolutionRoot = null;
}
}
Run it, and it should work. This worked for me, I hope it does for you too.
Further Reading :
Using Ninject – Dependency Injection with ASP.NET Web API controllers
I have a Web API project working using exactly the same solution as you from strathweb, so I just added a normal controller to the project, and it does work. Not a great help on it's own for you, so I'll detail the setup I've got:
I have the following packages installed (on the IOC side of things):
Ninject 3.0.1.10
Ninject MVC 3.0.0.6
Ninject.Web.Common 3.0.0.7
WebActivator 1.5.1
I have absolutely nothing in my Global.asax.cs file regarding Ninject, instead using the NinjectWebCommon.cs file that is automatically created in App_Start when you install Ninject. I don't know if by having code in your Global file that means that Ninject hasn't set itself up correctly in your project?
Here is the code in 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();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(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<IUserRepository>().To<UserRepository>().InSingletonScope();
kernel.Bind<IUserManager>().To<UserManager>();
}
}
Here's the other difference I can see between our code, where I create the Kernel, my code declares two bindings to the kernel.
Here's the code for my test controller, I can set a breakpoint in the constructor and it gets it:
public class TestController : Controller
{
IUserManager _userManager;
public TestController(IUserManager userManager)
{
_userManager = userManager;
}
//
// GET: /Test/
public ActionResult Index()
{
return View();
}
}
This works with both my Controller and my APIControllers.