简体   繁体   中英

C#, MVC, IoC, Dependency Injection

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?

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM