Ninject.ActivationException: Error activating IMainLicense
Asked Answered
D

1

5

I don't know fully how Ninject works that's why I'am asking this question here to figure out what's wrong.

If i create a empty constructor in ClaimsSecurityService it gets hit.

This is my error:

Error activating IMainLicense No matching bindings are available, and the type is not self-bindable. Activation path:

3) Injection of dependency IMainLicense into parameter mainLicenses of constructor of type ClaimsSecurityService

2) Injection of dependency ISecurityService into parameter securityService of constructor of type AccountController

1) Request for AccountController

Stack:

Ninject.KernelBase.Resolve(IRequest request) +474
   Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) +153
   Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) +747
   Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) +269
   Ninject.Activation.Providers.<>c__DisplayClass4.<Create>b__2(ITarget target) +69
   System.Linq.WhereSelectArrayIterator`2.MoveNext() +66
   System.Linq.Buffer`1..ctor(IEnumerable`1 source) +216
   System.Linq.Enumerable.ToArray(IEnumerable`1 source) +77
   Ninject.Activation.Providers.StandardProvider.Create(IContext context) +847
   Ninject.Activation.Context.ResolveInternal(Object scope) +218
   Ninject.Activation.Context.Resolve() +277
   Ninject.<>c__DisplayClass15.<Resolve>b__f(IBinding binding) +86
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +145
   System.Linq.Enumerable.SingleOrDefault(IEnumerable`1 source) +4059897
   Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) +169
   Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) +747
   Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) +269
   Ninject.Activation.Providers.<>c__DisplayClass4.<Create>b__2(ITarget target) +69
   System.Linq.WhereSelectArrayIterator`2.MoveNext() +66
   System.Linq.Buffer`1..ctor(IEnumerable`1 source) +216
   System.Linq.Enumerable.ToArray(IEnumerable`1 source) +77
   Ninject.Activation.Providers.StandardProvider.Create(IContext context) +847
   Ninject.Activation.Context.ResolveInternal(Object scope) +218
   Ninject.Activation.Context.Resolve() +277
   Ninject.<>c__DisplayClass15.<Resolve>b__f(IBinding binding) +86
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +145
   System.Linq.Enumerable.SingleOrDefault(IEnumerable`1 source) +4059897
   Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType) +145
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +87

[InvalidOperationException: An error occurred when trying to create a controller of type 'Successful.Struct.Web.Controllers.AccountController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +247
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +438
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +257
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +326
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +157
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Account controller:

public class AccountController : Controller
{
    private readonly ISecurityService _securityService;

    public AccountController(ISecurityService securityService)
    {
        _securityService = securityService;
    }

    //
    // GET: /Account/Login
    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }
}

NinjectWebCommon:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Http.Dependencies;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Extensions.Conventions;
using Ninject.Parameters;
using Ninject.Syntax;
using Ninject.Web.Common;
using Successful.Struct.Web;

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

namespace Successful.Struct.Web
{
    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>();
            kernel.Load("Successful*.dll");
            kernel.Bind(x => x.FromAssembliesMatching("Successful*.dll")
                  .SelectAllClasses()
                  .BindAllInterfaces()
                  );
            GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
            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)
        {
        }
    }

    public class NinjectResolver : NinjectScope, IDependencyResolver
    {
        private readonly 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)
        {
            var request = ResolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
            return ResolutionRoot.Resolve(request).SingleOrDefault();
        }
        public IEnumerable<object> GetServices(Type serviceType)
        {
            var request = ResolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
            return ResolutionRoot.Resolve(request).ToList();
        }
        public void Dispose()
        {
            var disposable = (IDisposable)ResolutionRoot;
            if (disposable != null) disposable.Dispose();
            ResolutionRoot = null;
        }
    }

}

ClaimsSecurityService:

public class ClaimsSecurityService : ISecurityService
    {
        private const string AscClaimsIdType = "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider";
        private const string SuccessfulStructWebNamespace = "Successful.Struct.Web";

        private readonly IMainLicense _mainLicenses;
        private readonly ICompany _companys;
        private readonly IAuthTokenService _authService;

        [Inject]
        public IApplicationContext ApplicationContext { get; set; }
        [Inject]
        public ILogger<LocationService> Logger { get; set; }

        public ClaimsSecurityService(IMainLicense mainLicenses, ICompany companys, IAuthTokenService authService)
        {
            _mainLicenses = mainLicenses;
            _companys = companys;
            _authService = authService;
        }
}
Dasilva answered 3/6, 2014 at 21:10 Comment(0)
B
7

NInject isn't quite completely automagical; you still need to tell it sometimes which implementations of your interfaces to create and inject (your "bindings" in NInject terms). Here is where they belong:

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

You should set up bindings for each of the services you're attempting to inject into your classes and controllers, in the proper scope. For example:

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IMainLicense>().To<MainLicense>();
    }

Here's a sample from one of my projects:

    private static void RegisterServices(IKernel kernel)
    {
        // Authentication
        kernel.Bind<IAuthenticationService>().To<AuthenticationService>().InRequestScope();

        // Entity Framework Unit of Work
        kernel.Bind<IUnitOfWork>().To<UnitOfWork>()
            .InRequestScope()
            .WithConstructorArgument("context", f => new DbContext("BlahBlahEntities"));

        // Document generator service
        kernel.Bind<IDocumentGeneratorService>().To<DummyDocumentGeneratorService>().InRequestScope();

        // Loggers
        kernel.Bind<ILog>().ToMethod(p => LogManager.GetLogger(p.Request.Target.Member.DeclaringType));
    }
Benefit answered 3/6, 2014 at 21:15 Comment(5)
If you look at my CreateKernel class, doesn't the .load and .bind fix what you are describing?Dasilva
@StefanKarlsson: I've never used NInject that way. A quick look through the documentation would have me believing that you're attempting to bind all classes to all interfaces, which I'm not sure you'd want (not all classes implement all interfaces).Ribbentrop
Well that is right @Cory. I want to bind all none abstract classes to its matching interface. So i don't think the error is there.Dasilva
Do you know if NInject knows how to match a class to its interface using the method you've implemented?Ribbentrop
yes i do, done it in another project. Trying to look at that now but i can't find the differences.Dasilva

© 2022 - 2024 — McMap. All rights reserved.