-1

Here is my BaseController:

     using Ferrero.Data; 
     using System; 
     using System.Collections.Generic;
     using System.Linq; using System.Web; using System.Web.Mvc;

     namespace Ferrero.Web.Controllers 
     {
         public abstract class BaseController : Controller
         {
             protected IFerreroUow Uow { get; set; }
             public MasterLayoutView masterlayout = new MasterLayoutView();
         } 
      }

And here is my HomeController which inherits from BaseController:

using Ferrero.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Ferrero.Model;

namespace Ferrero.Web.Controllers
{
    public class HomeController : BaseController
    {
        public HomeController(IFerreroUow uow)
        {
            Uow = uow;
        }

        public ActionResult Index()
        {
            ViewBag.Title = "Home Page";
            masterlayout.employees_list = Uow.Employees.GetAll().ToList();
            return View();
        }
    }
}

The Uow is a unit of work where I have all my Repositories and I want it to be available in every controller. The thing is that I am not using the Ioc correctly and I get this error when I run the application

An error occurred when trying to create a controller of type 'Ferrero.Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.

Can anyone help me please?

Give IT
  • 192
  • 2
  • 19
  • 2
    Which IoC container are you using and is it designed to work with ASP.NET MVC? If not, you should use one that is. I use https://www.nuget.org/packages/Ninject.MVC3/ – Luke Jul 16 '16 at 19:12
  • 1
    I installed Ninject.MVC5 and I get the following errors Error activating IFerreroUow No matching bindings are available, and the type is not self-bindable. Activation path: 2) Injection of dependency IFerreroUow into parameter uow of constructor of type HomeController 1) Request for HomeController Suggestions: 1) Ensure that you have defined a binding for IFerreroUow. 2) If the binding was defined in a module, ensure that the module has been loaded into the kernel. – Give IT Jul 16 '16 at 19:21
  • 1
    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. – Give IT Jul 16 '16 at 19:22
  • 1
    Johnny, I asked you which IoC container you are using, not to just go and blindly install the one I suggested :p Which IoC container are you using or had installed to your solution _before_ I mentioned that I use Ninject for ASP.NET MVC? – Luke Jul 16 '16 at 19:23
  • sorry.. I had nuget.org/packages/Ninject – Give IT Jul 16 '16 at 19:38
  • 1
    Ok great, so it's Ninject. Now that you have the MVC plugin installed it will work... you just need to learn how to use it. You need to tell Ninject what to resolve the interface `IFerreroUow` to, using a binding. You will do this within a Ninject Module. Search for `NinjectModule` within your solution. Info on [this page](https://github.com/ninject/Ninject.Web.Mvc/wiki/Dependency-injection-for-controllers) and [this page](https://github.com/ninject/Ninject.Web.Mvc/wiki/Setting-up-an-MVC3-application) and [this page](https://github.com/ninject/Ninject/wiki/Modules-and-the-Kernel) – Luke Jul 16 '16 at 19:44
  • 1
    See: https://stackoverflow.com/a/15910758/264697 – Steven Jul 16 '16 at 21:33
  • 1
    For what it's worth, Ninject sounds a whole lot more complicated than Windsor. Create an MVC project, add the `Castle.Windsor.Web.Mvc` nuget package, and it provides all of the bootstrapping. Those steps only take a few seconds. All you have to do is configure your dependencies. – Scott Hannen Jul 17 '16 at 01:08
  • 1
    Have you considered not using a container at all, and just using Pure DI? Keep it simple to start with and only bring in a container if needed. http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer – tomliversidge Jul 17 '16 at 06:24
  • 1
    For example see https://www.kenneth-truyers.net/2014/11/18/how-to-use-pure-di – tomliversidge Jul 17 '16 at 06:30
  • @tomliversidge can you please provide me an answer using pure DI? – Give IT Jul 18 '16 at 06:40
  • @JohnnyGolem ok please see answer below – tomliversidge Jul 18 '16 at 12:45

2 Answers2

3

Sometimes you do not need a container at all :) You just need to know the Composition Root. Example of how to do this in WebApi and MVC without using a container AKA Pure DI:

public interface ISingleton : IDisposable { }
public class TransientDependency { }

public class Singleton : ISingleton
{
    public void Dispose() { }
}

// IHttpControllerActivator is for WebApi, IControllerFactory for MVC
public class CompositionRoot : IDisposable, IHttpControllerActivator, IControllerFactory
{
    private readonly ISingleton _singleton;

    // pass in any true singletons i.e. cross application instance singletons
    public CompositionRoot()
    {
        // intitialise any application instance singletons
        _singleton = new Singleton();
    }

    public void Dispose()
    {
        _singleton.Dispose();
    }

    // Web API
    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        // Per-Request-scoped services are declared and initialized here
        if (controllerType == typeof(SomeApiController))
        {
            // Transient services are created and directly injected here
            return new SomeApiController(_singleton, new TransientDependency());
        }

        var argumentException = new ArgumentException(@"Unexpected controller type! " + controllerType.Name,
            nameof(controllerType));
        Log.Error(argumentException, "don't know how to instantiate API controller: {controllerType}", controllerType.Name);
        throw argumentException;
    }

    // MVC
    public IController CreateController(RequestContext requestContext, string controllerName)
    {
        if (controllerName.ToLower() == "home")
        {
            return new HomeController(_singleton, new TransientDependency());
        }

        var argumentException = new ArgumentException(@"Unexpected controller! " + controllerName);
        Log.Error("don't know how to instantiate MVC controller: {controllerType}. redirecting to help", controllerName);
        throw argumentException; // Alternatively would return some default Page Not Found placeholder controller;
    }

    // MVC
    public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
    {
        return SessionStateBehavior.Default; 
    }

    // MVC
    public void ReleaseController(IController controller)
    {
        // anything to clean up?
    }
}

public static class DependencyInjection
{
    public static void WireUp()
    {
        var compositionRoot = new CompositionRoot();

        System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(compositionRoot);
        System.Web.Http.GlobalConfiguration.Configuration.Services.Replace(typeof (IHttpControllerActivator), compositionRoot);
    }
}
tomliversidge
  • 2,219
  • 1
  • 11
  • 14
0

I found my solution here!!! Thanks to this guy! Anyone who wants to implement Ninject to mvc this is the best example.

Give IT
  • 192
  • 2
  • 19