Search code examples
c#asp.netasp.net-mvcmockingninject

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


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.


Solution

  • 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!