Шаблон проектирования для базового контроллера с внедрением зависимостей - MVC 3 + Ninject - PullRequest
4 голосов
/ 12 октября 2011

У меня есть этот шаблон

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

так что я могу сделать что-то вроде этого

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

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

во всем моем контроллере. Я уверен, что это антипаттерн для 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) { }

    ...
}

но это решение требует, чтобы я вставил все зависимости во все контроллеры и обновил весь конструктор, если мне нужна новая глобальная переменная (например, rep) или новая личная переменная для basecontroller (например, man).

Какой схеме мне следовать и почему?

Редактировать Я нашел этот вопрос и этот , но все еще не могу понять, каким шаблонам проектирования следует следовать.

Ответы [ 2 ]

3 голосов
/ 12 октября 2011

Не похоже, что вам нужен BaseController в этом случае. Я думаю, что было бы легче (и более проверяемым) сделать что-то вроде этого:

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

Тогда ваш контейнер IoC может автоматически подключать все эти зависимости для каждого контроллера.

0 голосов
/ 12 октября 2011

Я не думаю, что с тонким решением вам нужно всегда объявлять rep, man и env.Вы можете воспользоваться преимуществами стандартных / дополнительных параметров.

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

Тогда вы можете использовать именованные назначения параметров:

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

    ...
}
...