0
votes

In my ASP .NET MVC WebApi project I have controller constructor that receive a parameter, I don't have a prameterless constructor.

The dependecies are injected using Ninject:

  • Ninject 3.2.0.0 (3.2.2)
  • Ninject.Web.Common 3.2.0.0 (3.2.3)
  • Ninject.Web.WebApi 3.2.0.0 (3.2.4)

When I call the API I get:

An exception of type 'Ninject.ActivationException' occurred in Ninject.dll but was not handled in user code

Additional information: Error activating IHubRepository

No matching bindings are available, and the type is not self-bindable.

Activation path:

2) Injection of dependency IHubRepository into parameter repHub of constructor of type ResultController

1) Request for ResultController

Suggestions:

1) Ensure that you have defined a binding for IHubRepository.

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.

The code is the following.

Controller:

public class ResultController : BaseHubController
{
    public ResultController(IHubRepository repHub)
    {
        _rep = repHub;
    }

    public async Task<IHttpActionResult> Get(string fileName)
    {
        if (String.IsNullOrEmpty(fileName))
            return BadRequest();


        return Ok();
    }
}

NinjectResolver

public sealed class NinjectResolver : NinjectScope, IDependencyResolver
{
    private IKernel kernel;

    public NinjectResolver(IKernel kernelParam)
        : base(kernelParam)
    {
        kernel = kernelParam;
        AddBindings();
    }
    public IDependencyScope BeginScope()
    {
        return new NinjectScope(kernel.BeginBlock());
    }

    public void AddBindings()
    {
        kernel.Bind<Hub.Dal.IHubRepository>().To<Hub.Dal.HubRepository>();
        kernel.Bind<System.Data.Entity.DbContext>().To<Hub.Dal.Context>();
    }
}

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;
    }
}

IHubRepository

public interface IHubRepository
{
    bool LogRequest(SHApiLog logData);
}

HubRepository

public class HubRepository : IHubRepository
{
    private DbContext _ctx;

    public HubRepository(DbContext curCtx)
    {
        this._ctx = curCtx;
    }

    public bool LogRequest(SHApiLog logData)
    {
        try
        {
            _ctx.Set<SHApiLog>().Add(logData);
            _ctx.SaveChanges();
        }
        catch (Exception)
        {
            return false;
        }

        return true;
    }
}

I can't understand why it won't work.

2
Did you haphazardly misspelled something when setting up Ninject? The error is complaining about ISistemiHubRepository as you can see here: Injection of dependency ISistemiHubRepository into parameter repHub of constructor of type ResultController. It is not complaining about IHubRepositoryCodingYoshi
@CodingYoshi sorry, fixed the text; sadly is not a typo related issueIrvin Dominin
I have a feeling it has to do with this: public HubRepository(DbContext curCtx) because it needs a parameter to be instantiated. Do a test and put an empty constructor there and see if the error goes away, if it does then you know that is the issue. Then to fix the issue, you may need to use this during binding: .WithConstructorArgument("curCtx", .new DbContext /*or whatever*/);CodingYoshi
@CodingYoshi I tried but now I get an context issue because it can't be called on init this.Configuration.ProxyCreationEnabled = false; Riga 18: this.Configuration.LazyLoadingEnabled = false; Riga 19: ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 90;Irvin Dominin
Ok so the issue was related to the constructor? This is another error so you need to figure how to fix it.CodingYoshi

2 Answers

1
votes

The error message already states the possible problems. Since the relevant code is not making any use of modules you can disregard the options mentioning modules and module loading => 2) and 5). Since you're not using named parameters you can also ignore 4)

For number 1) => missing binding, there's also the possibility that you have two different IHubRepository (in different namespaces) and furthermore have created a binding for one of these but not the one you're requesting. You have a binding for Hub.Dal.IHubRepository but maybe ResultController wants Foo.Bar.IHubRepository.

To check for multiple kernels you can resort to service locator - inject IKernel (or IResolutionRoot) into the Controller instead of IHubRepository. Set a breakpoint at the controller constructor and inside the controller of NinjectResolver. When hitting the first break point, set object ID on the kernel reference. When hitting the second, check if there's an object ID and if it's the same. If it isn't.. well then you've got multiple kernels.

0
votes

I banged my head for two days, by adding, changing and removing references to Ninject, changing the code and so on..

Solved with a complete delete of the solution and a new, clear get from TFS.

Probably there was a pesky reference somewhere in the code; I'm so sad.