【问题标题】:injecting dependency into controller constructor or use a property将依赖项注入控制器构造函数或使用属性
【发布时间】:2018-04-03 06:58:41
【问题描述】:

在我们的代码库中有一个基本控制器和一个派生控制器。在名为BaseController 的基本控制器中,使用如下属性注入依赖项。

private IAuditRepository _audit;

protected IAuditRepository Audit
{
    get { return _audit ?? (_audit = DependencyResolver.Current.GetService<IAuditRepository>()); }
}

并且继承基控制器的派生控制器也被多个控制器继承。假设这个派生控制器称为BaseProjectController。这个控制器有一个ProjectRepository,所以代码的原始作者没有遵循BaseController中给出的相同方法,而是在构造函数中注入这个存储库,如下所示。

private IProjectRepository _projectRepository;
protected BaseProjectController(IProjectRepository projectRepository)
{
    _projectRepository = projectRepository;
}

因此任何与Project 相关的控制器都将继承BaseProjectController,并且每个控制器都需要实现类似的sn-p 代码。

public class ProjectActivityController : BaseProjectController
{
    public ProjectActivity(IProjectRepository projectRespository)
     :base(projectRespository) { }
}

我发现使用第一种方法很容易,只需从继承BaseProjectController 的控制器调用属性,而不需要将其注入构造函数中。

问题是,当您可以在BaseController 中遵循相同的方法时,为什么要采用这种方法?两者有什么区别?为什么你会选择第一种方法而不是第二种方法 - 反之亦然?

【问题讨论】:

  • 反对解析器(服务定位器)方法的主要论据之一是可测试性。但我猜,从所有的继承层来看,无论如何你都不会做太多的单元测试。
  • 还有第三种选择:完全移除基类。您的IAuditRepository 似乎是一个横切关注点,并且通常有更有效且可维护的方法来实现横切关注点而不是基类。但为了给您提供建议,需要更多信息。

标签: c# asp.net-mvc dependency-injection repository


【解决方案1】:

我可以描述这两种方法的优缺点,所以,你自己决定。

构造函数注入

优点:

  1. 您可以在一处查看所有依赖项
  2. Service Locator 反模式 - 您的代码不依赖于特定容器 (DependencyResolver)

缺点:

  1. 您应该将所有依赖项从子类传递到基类(需要编写更多代码)

属性注入

反之亦然:)

所以,比较利弊并做出决定。

【讨论】:

  • 如果我错了,请纠正我,但是对于属性注入,我不需要将依赖项从子类传递到基类。我只需要从基类调用属性
  • @rpmansion 对我来说,我更喜欢构造函数注入。我认为这更清楚
猜你喜欢
  • 2021-09-08
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-02
相关资源
最近更新 更多