简体   繁体   English

具有依赖注入的基本控制器的设计模式 - MVC 3 + Ninject

[英]Design pattern for a base controller with dependecy injection - MVC 3 + Ninject

I've got this pattern 我有这种模式

public abstract class BaseController : Controller
{
    readonly RepositoryFactory _rep;
    protected RepositoryFactory rep
    {
        get
        {
            return _rep;
        }
    }

    readonly ManageRoles _man;

    readonly ElementAvailableForUser _env;
    protected ElementAvailableForUser env
    {
        get
        {
            return _env;
        }
    }

    public BaseController()
      : this(DependencyResolver.Current.GetService<RepositoryFactory>(),
             DependencyResolver.Current.GetService<ManageRoles>(),
             DependencyResolver.Current.GetService<ElementAvailableForUser>()) { }

    public BaseController(RepositoryFactory rep, ManageRoles man, ElementAvailableForUser env)
    {
        _rep = rep;
        _man = man;
        _env = env;
    }
}

so I am able to do something like this 所以我能够做这样的事情

public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View(rep.Offers.GetAll());
    }

    public ActionResult Sections()
    {
        return View(env);
    }
}

in all my controller. 在我的所有控制器中。 I'm sure this is antipattern for DI and IoC, so I thin a solution like this 我确信这是DI和IoC的反模式,所以我简化了这样的解决方案

public abstract class BaseController : Controller
{
    ...

    // removed empty constructor

    public BaseController(RepositoryFactory rep, ManageRoles man, ElementAvailableForUser env)
    {
        _rep = rep;
        _man = man;
        _env = env;
    }
}

public class HomeController : BaseController
{
    public HomeController(RepositoryFactory rep, ManageRoles man, ElementAvailableForUser env) : base(rep, man, env) { }

    ...
}

but this solution requires me to insert all dependencies in all controllers and update all constructor if I need a new global variable (like rep) or a new private variable for basecontroller (like man). 但是这个解决方案要求我在所有控制器中插入所有依赖项并更新所有构造函数,如果我需要一个新的全局变量(如rep)或一个新的私有变量用于basecontroller(如man)。

Which pattern should I follow and why? 我应该遵循哪种模式?为什么?

Edit I found this question , and this , but still I can't understand which design patterns should I follow. 编辑我发现这个问题 ,而这个 ,但我仍然无法理解其设计模式,我应该遵循。

It doesn't seem like you need the BaseController in this case. 在这种情况下,您似乎不需要BaseController。 I think it would be easier (and more testable) to do something like this: 我认为做这样的事情会更容易(也更容易测试):

    public class HomeController : Controller
    {
        private readonly IRepository<Offers> _repository;
        private readonly RoleManager _roleManager;
        private readonly UserManager _userManager;

        public HomeController(IRepository<Offers> repository, RoleManager roleManager, UserManager userManager)
        {
            _repository = repository;
            _roleManager = roleManager;
            _userManager = userManager;
        }
    }

Then you could have your IoC container wire up all of those dependencies automatically for each controller. 然后,您可以让您的IoC容器自动为每个控制器连接所有这些依赖项。

I don't think with the thin solution you need to always declare rep, man, and env. 我不认为你需要总是声明rep,man和env。 You could take advantage of default/optional parameters. 您可以利用默认/可选参数。

public BaseController(RepositoryFactory rep = null, ManageRoles man = null, ElementAvailableForUser env = null)
{
    _rep = rep;
    _man = man;
    _env = env;
}

Then you can use named parameter assignments: 然后您可以使用命名参数分配:

public class HomeController : BaseController
{
    public HomeController(ManageRoles man) : base(man: man) { }

    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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