【问题标题】:Constructor over-injection due to presentation layer 'dashboard'由于表示层“仪表板”而导致的构造函数过度注入
【发布时间】:2014-05-09 19:03:54
【问题描述】:

我的表示层(Web 应用程序)上的控制器目前存在一些设计问题。该网站应该提供某种仪表板,显示将从多个存储库收集的所有类型的信息。我想显示最新的.. 警报消息时间线事件报告统计...

public class HomeController : Controller {

    public HomeController(
        IAlertRepository alertRepository, 
        IAccountRepository accountRepository, 
        ITimelineRepository timelineRepository,
        IReportingRepository reportRepository) {
        // ...
    }

}

这完全导致了构造函数过度注入,由于许多原因,这很尴尬。我怎样才能克服这个问题?显示所有信息是我们客户的要求。

【问题讨论】:

  • 如果构造函数参数列表太长,那么也许您可以使用服务定位器之类的东西而不是使用构造函数注入并通过它延迟加载存储库对象?
  • HomeController 做了多少工作?也许应该只提供一组通用的IRepository 对象?也就是说,你有几个?如果这是一个顶级仪表板,那么只有 4 个还不错,而且非常易于管理。

标签: c# asp.net-mvc dependency-injection domain-driven-design


【解决方案1】:

不确定这是否适合您,但您可以考虑为每个仪表板对象创建完全独立的控制器

例如

AlertsController
AccountsController
TimelineController
ReportsController

然后您只需向每个中注入一个存储库。每个控制器将呈现一个Partial View,您将通过 Ajax 从客户端调用它们,每个控制器的内容类型为text/html,然后将返回的标记插入到您的主文档中相关的容器元素(例如 @ 987654324@)

在这方面,HomeController 将被降级为更多的“引导者”角色,仅用于加载初始页面框架和客户端脚本。

这种方法的优点是您的仪表板小部件可以异步加载、独立刷新、单独重复使用,而且允许用户选择不同的组合或者实际上只是在新窗口中单独打开不同的小部件非常容易,等等,没有额外的代码。

当然,这可能不适合您的应用程序的上下文 :)

【讨论】:

  • 这是我自己提出的一个好主意,因为根据我的经验,在仪表板上拥有许多单独的小部件是一种非常常见的“实践”。但是,该项目还有另一个要求是尽可能减少和捆绑请求。如果仪表板需要显示 10 个不同的东西,那么我需要制作 10 个部分,它们向 10 个控制器调用 10 个请求。我认为我们的领域专家不会对此感到高兴。
  • 这是一个公平的观点;也许您可以使用来自客户端的单个请求,指示您想要的小部件、它们的参数等,并使用 HomeController 上的 HttpClient 发出 10 个单独的请求(本地请求的开销非常低),组装生成的 HTML在您的 Index 视图中,并在一次往返中从 HomeController 返回。
【解决方案2】:

构造函数过度注入告诉你HomeController 做的太多了。控制器负责将模型/数据发送到视图并获取用户输入以将其传递到适当的服务中。

您在这里错过了这项服务。创建一个与存储库对话以查找相关数据并具有操作它们的所有业务逻辑的服务(现在您可能在控制器中拥有它,破坏了SRP)。不过,如果您的服务类与太多存储库通信,请将其拆分为更多服务类,每个服务类一个角色。

您最终可能会多出 2-3 个类,但这些可以从其他控制器或服务中重用,并且您的设计将变得更加模块化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    相关资源
    最近更新 更多