Problem
I am trying to test my service. when I run test it show this error and test failed. my unity config class is in my asp.net mvc project and my test is in different project I don't know where I am doing wrong.
unable to get default constructor for Class servicetest
ServiceTest
[TestClass]
public class ImportServiceTests
{
private readonly IImportService _importService;
private readonly IUnitOfWork _unitOfWork;
public ImportServiceTests(IImportService importService, IUnitOfWork unitOfWork)
{
_importService = importService;
_unitOfWork = unitOfWork;
}
[TestMethod]
public void ImportCategories()
{
string filePath = Path.GetFullPath(#"E:\categories.xlsx");
if (File.Exists(filePath))
{
Stream data = File.OpenRead(filePath);
string fileName = Path.GetFileName(filePath);
_importService.ImportCategoriesFromXlsx(data);
}
}
}
UnityConfig
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<IUnitOfWork, UnitOfWork>(new PerRequestLifetimeManager());
container.RegisterType<IImportService, ImportService>(new PerRequestLifetimeManager());
container.RegisterType<IDataContext, PriceHunterDataContext>(new PerRequestLifetimeManager());
}
}
Related
I have a third-party library that gives me the opportunity to connect NLog via an ILoggerFactory interface.
However, I would like to add a suffix to the logger namespace.
The following ExtensionMethod is currently used to inject NLog.
var factory = LoggerFactory.Create(builder => builder.AddNLog());
Currently, a namespace looks like this:
my.custom.library.class1
my.custom.library.class2
my.custom.library.with.inner.subclass
However, I would like that behind every namespace there is e.g. foo
my.custom.library.class1.foo
my.custom.library.class2.foo
my.custom.library.with.inner.subclass.foo
Here's a quick fix without any overloads.
var factory = LoggerFactory.Create(builder => builder.AddNLogWithSuffix(_IpSuffix));
public static class LoggingBuilderExtensions
{
public static void AddNLogWithSuffix(this ILoggingBuilder builder, string loggerSuffix)
{
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, NLogLoggerProviderWithSuffix>(_ => new NLogLoggerProviderWithSuffix(new NLogProviderOptions(), LogManager.LogFactory, loggerSuffix)));
}
}
[ProviderAlias("NLog")]
public class NLogLoggerProviderWithSuffix : ILoggerProvider
{
private readonly NLogLoggerProvider _NLogLoggerProvider;
private readonly string _LoggerSuffix;
/// <summary>New provider with options and a suffix</summary>
/// <param name="options"></param>
/// <param name="logFactory">Optional isolated NLog LogFactory</param>
/// <param name="loggerSuffix"></param>
public NLogLoggerProviderWithSuffix(NLogProviderOptions options, LogFactory logFactory, string loggerSuffix)
{
_LoggerSuffix = loggerSuffix;
_NLogLoggerProvider = new NLogLoggerProvider(options, logFactory);
}
public void Dispose()
{
_NLogLoggerProvider.Dispose();
}
public ILogger CreateLogger(string categoryName)
{
return _NLogLoggerProvider.CreateLogger($"{categoryName}.{_LoggerSuffix}");
}
}
I've been reading about the these two approaches to resolving dependencies and found some sample code for ninject implementations.
For service locator followed something like
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}
And
public class NinjectDependencyScope : IDependencyScope
{
IResolutionRoot resolver;
public NinjectDependencyScope(IResolutionRoot resolver)
{
this.resolver = resolver;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has been disposed");
return resolver.TryGet(serviceType);
}
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);
}
public void Dispose()
{
IDisposable disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
}
And the out of the box class
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);
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(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<MembersService>().To<MembersService>();
kernel.Bind<MemberContext>().To<MemberContext>();
}
For composition root I followed - https://gist.github.com/paigecook/3860942
public class NinjectKernelActivator: IHttpControllerActivator
{
private readonly IKernel _kernel;
public NinjectKernelActivator(IKernel kernel)
{
_kernel = kernel;
}
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
var controller = (IHttpController) _kernel.Get(controllerType);
request.RegisterForDispose( new Release(()=> _kernel.Release(controller)));
return controller;
}
}
internal class Release : IDisposable
{
private readonly Action _release;
public Release(Action release)
{
_release = release;
}
public void Dispose()
{
_release();
}
}
And made a single change to Create(..) in NinjectWebCommon.
//GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
GlobalConfiguration.Configuration.Services.Replace(
typeof(IHttpControllerActivator),
new NinjectCompositionRoot(kernel));
EDIT
Controller and service creation
public class MembersController : ApiController
{
private readonly IMembersService _membersService;
public MembersController(IMembersService membersService)
{
_membersService = embersService;
}
...
}
public class MembersService : IMembersService
{
private readonly MembersContext _context;
public MembersService(MemberContext context)
{
_context = context;
}
...
}
Have I correctly implemented the Composition Root?
I don't really see what the difference is between the two approaches?
The difference between Composition root (which is how you should do dependency injection) and Service Locator is that composition root should be in one place of the application (as close as possible to the application's entry point). This doesn't mean that it will be invoked only once. For example in case of MVC/WebAPI good place for composition root is the controllers factory which creates controllers for every HTTP request application receives. The point is that composition root implemented in controller factory should create entire object graph (controller with all of his dependencies) that is required do handle the request such that no other dependencies need to be resolved from container separately during this request.
Service Locator on the other hand is approach where you retrieve your dependencies from service locator whenever you need them. Service locator becomes ambient context in your application (usually provides static ServiceLocator.Get<T>() method). Service Locator is the opposite of Dependency Injection because instead of injecting your dependencies you are retrieving them when you need them. This means having ServiceLocator.Get<T>() method calls all over the application code and all layers of your application have dependency on service locator. This approach has several downfalls one of them is the fact that it makes code harder to unit test, since all tests need to interact with the same global service locator class to set the fake dependencies of a class under test.
Your NinjectKernelActivator implementation of composition root is correct assuming you are not exposing IKernel elsewhere in some public static property for using it later to get dependencies that you do not inject.
I am struggling to make this work. I've got Unity and Unity.AspNet.WebApi packages (v 3.5.1404) installed and below activation code which came with the packages
public static class UnityWebApiActivator
{
/// <summary>Integrates Unity when the application starts.</summary>
public static void Start()
{
var container = UnityConfig.GetConfiguredContainer();
var resolver = new UnityHierarchicalDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
// DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
/// <summary>Disposes the Unity container when the application is shut down.</summary>
public static void Shutdown()
{
var container = UnityConfig.GetConfiguredContainer();
container.Dispose();
}
}
and my type registration looks like this:
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IAuditService, AuditService>(
new PerThreadLifetimeManager(),
new InjectionConstructor(new SecurityDbContext()));
}
So far I've tried PerThreadLifetimeManager and TransientLifetimeManager with no success. I've also got the Unity.Mvc package and tried using the PerRequestLifetimeManager as suggested by msdn but no luck. It always gives me the same instance of dbcontex.
I rather do not include any MVC dependency as this is purely WebApi but when I try to use Unity.Mvc, I ended up some http runtime errors too.
Anyone has a good suggestion/example to resolve dbcontext per request with Unity in WebApi, preferably without any mvc dependency?
The way I was injecting db context was the problem here. Unity remembers the instance created and injects the same instance for all new AuditService instance created. I simply needed to resolve the db context as below.
container.RegisterType<DbContext, SecurityDbContext>(new PerThreadLifetimeManager());
PerThreadLifetimeManager did the work and it should be fine considering each web requests will be served by a different thread.
I managed to resolve per request by declaring my custom UnityResolver's class within the WebApiConfig class. The UnityResolver class uses the HttpConfiguration class assuming you're using an OWIN context.
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var _container = new UnityContainer();
DependencyConfiguration.ConfigureContainer(_container);
config.DependencyResolver = new UnityResolver(_container);
}
The ConfigureContainer class is simply a class where I declare my IOC dependencies as shown below:
private static void RegisterReleaseEnv(IUnityContainer container)
{
//Repository Registration
container
.RegisterType(typeof(IRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager());
}
It is very important that you use the HierarchicalLifetimeManager lifetime manager so that you get a new instance per request.
The UnityResolver class then looks like this:
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
I then get a new DB Context using a Generic Repistory as shown below:
public class GenericRepository<TEntity> : IRepository<TEntity>, IDisposable where TEntity : class
{
internal BackendContainer context;
internal DbSet<TEntity> dbSet;
public GenericRepository(BackendContainer context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public GenericRepository()
: this(new BackendContainer())
{
}
public virtual IQueryable<TEntity> All()
{
return dbSet.AsQueryable();
}
}
Because of the Unity Resolver, the Generic Repository is instantiated per request and so is the DbContext (BackendContainer).
I hope this helps.
For more information: http://www.asp.net/web-api/overview/advanced/dependency-injection
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.