我有一个使用UnitOfWork Interfaces和Managers的项目设置。所有这一切都很好,而我只需要使用accountMananger作为我的控制器的基础。
protected BaseController(IAccountManager acctManager)
{
_accountManager = acctManager;
}
我的控制器是这样创建的,并且有效。
public class AccountController : BaseController
{
public AccountController(IAccountManager accountManager)
: base(accountManager)
{
}
现在我正在创建其他业务经理,我意识到在项目结束时我的BaseController构造函数将会很大,或者我将根据我所在的控制器加载各种签名。如果我忘记了某些内容并需要另一个管理员并更改了一个构造函数,那么所有其他控制器也需要更改。
我的意思是,我实际上总是希望在基础中注入/解析accountManager。我能这样做吗?由于我99%检查授权。
我已经阅读过关于ControllerFactories的内容,但也有人提到要实现IDependancyResolver
,但没有例子,这是他首选的方法。
我可以看到,基于我需要的控制器创建构造函数会成为一个很大的负担,我还没有。
任何机构都可以给我一个如何轻松访问基地经理的例子,因为我需要它们。我的意思是,无论如何,他们都创造并准备好解决..所以为什么我需要以一种奇怪的方式传递它们呢?
对不起。只是学习DI,这是一个很好的教程,但你可以看到缺乏一些进一步的解释。
答案 0 :(得分:2)
您与帐户经理的相关信息称为Cross-Cutting Concern。有一些不同的方法可以为这只猫设置皮肤,但你应该避免在每个控制器中注入相同的依赖关系。
通常,避免继承也更好,因为这会导致类之间的紧密耦合。这里的紧耦合很明显 - 如果你需要一个以后没有IAccountManager
作为依赖的控制器怎么办呢?
在这种特殊情况下,MVC中已经存在一个内置的松散耦合授权框架,您可以使用AuthorizeAttribute,这是处理对控制器操作方法的访问的常用方法。
[Authorize]
public class AccountController : Controller
{
public AccountController () { . . . }
[AllowAnonymous]
public ActionResult Register() { . . . }
public ActionResult Manage() { . . . }
public ActionResult LogOff() { . . . }
}
还有其他一些实施跨领域问题的方案 - 使用IActionFilter
实施see this for a DI friendly example - interception,Decorator Pattern(某些DI容器支持),并将依赖项放在环境上下文中(例如HttpContext.Items)。
我可以看到,基于我需要的控制器创建构造函数会成为一个很大的负担,我还没有。
这就是为什么你应该继承DefaultControllerFactory
并在应用程序启动时(在composition root中)为它提供DI容器的一个实例。容器通常负责向控制器提供依赖项,尤其是在应用程序很大的情况下。
public class AutofacControllerFactory
: DefaultControllerFactory
{
private readonly IContainer container;
public InjectableControllerFactory(IContainer container)
{
if (container == null)
throw new ArgumentNullException("container");
this.container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (requestContext.HttpContext.Request.Url.ToString().EndsWith("favicon.ico"))
return null;
return controllerType == null ?
base.GetControllerInstance(requestContext, controllerType) :
this.container.Resolve(controllerType) as IController;
}
}
我强烈建议您阅读本书Dependency Injection in .NET。 DI是软件开发中最容易被误解的概念之一,非常值得投资自己详细研究这个主题,而不必在互联网上筛选错误的信息。通过正确使用DI可以获得许多好处,但使用不当往往比不使用DI更糟糕。