C# 具有依赖注入的基本控制器的设计模式-MVC 3+;尼尼特
我有这个图案C# 具有依赖注入的基本控制器的设计模式-MVC 3+;尼尼特,c#,asp.net-mvc-3,design-patterns,dependency-injection,inversion-of-control,C#,Asp.net Mvc 3,Design Patterns,Dependency Injection,Inversion Of Control,我有这个图案 public abstract class BaseController : Controller { readonly RepositoryFactory _rep; protected RepositoryFactory rep { get { return _rep; } } readonly ManageRoles _man; readonly Ele
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;
}
}
在我所有的控制器中。
我确信这是DI和IoC的反模式,所以我精简了这样一个解决方案
public class HomeController : BaseController
{
public ActionResult Index()
{
return View(rep.Offers.GetAll());
}
public ActionResult Sections()
{
return View(env);
}
}
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),则更新所有构造函数
我应该遵循哪种模式?为什么
编辑
我发现了这一点,但我仍然不知道应该遵循哪些设计模式。我认为,对于精简解决方案,您不需要总是声明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) { }
...
}
在这种情况下,您似乎不需要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;
}
}
公共类HomeController:控制器
{
专用只读IRepository存储库;
专用只读角色管理器(RoleManager);
私有只读用户管理器_UserManager;
公共HomeController(IRepository存储库、角色管理器角色管理器、用户管理器用户管理器)
{
_存储库=存储库;
_roleManager=roleManager;
_userManager=userManager;
}
}
然后,您可以让您的IoC容器为每个控制器自动连接所有这些依赖项。是什么让您认为有一种设计模式应该遵循?因为在我的应用程序中只应使用其中一种模式。是的,但在这种情况下,IoC不起作用并且“人”如果未在子控制器中显式声明,则结果始终为null。是的,可能是这样,但我需要以相同的方式为所有控制器填充对象,我在基本控制器的actionexecuting方法中执行此操作。