【问题标题】:MVC: Should the Repository be instantiated in the Controller or each Action?MVC:Repository 应该在 Controller 还是每个 Action 中实例化?
【发布时间】:2014-02-16 23:23:58
【问题描述】:

标题确实说明了一切。我有一些根本不使用存储库的 Action 方法,例如仅显示静态页面的 Index() 方法。

public ActionResult Index()
{
    return View();
}

在我看来,在这些情况下,在控制器中实例化存储库是浪费时间......但对于 IoC,我想提交一个接口,因此必须在控制器中进行:

public PerfMvcController(IPerfRepository repo)
{
    repo = repo ?? new PerfRepository();
}

简而言之,我会对使用 IoC 在控制器中实例化存储库的最佳实践感兴趣。

【问题讨论】:

标签: c# asp.net-mvc controller repository inversion-of-control


【解决方案1】:

什么更浪费?

  1. 到处复制代码,或者
  2. 单行初始化(DRY 原则)

在构造函数中注入存储库被普遍接受的原因是因为它使依赖关系清晰,(它们在一个地方并且只在一个地方)

仅通过检查构造函数就可以清楚依赖关系,而不是深埋在实现中。您可能在早期阶段没有注意到这一点,因为您只有基本功能 (CRUD),但随着应用程序的增长,您将开始注意到不必寻找依赖项的优势。

如果您担心性能,大多数 ORM(如果您正在使用)都有延迟初始化。

另一种常见的做法是在其他地方(IoC 容器)实例化存储库,然后注入到控制器的构造函数中。

离题

repo = repo ??新的 PerfRepository();

在控制器中构建自己的具体存储库会增加耦合,因此打破 IoC 模式。相反,您应该在 null 时抛出异常,而且它支持fail-fast technique(一种构建高质量应用程序的技术)

【讨论】:

  • 清晰简洁 - 感谢您提供有关快速失败技术的额外提示!
【解决方案2】:

我认为你最好通过控制器的构造函数注入你的IPerfRepository,而不是在你的操作中复制代码。

如果您担心存储库的构造函数很重,并且无论您是否使用存储库都执行它,您可以考虑使用支持注入Lazy<T> 的 IoC 容器。

Autofac 就是一个很好的例子:对于使用 Autofac 注册的任何服务,例如您的IPerfRepository,您可以请求Lazy<IPerfRepository>。这样一来,除非您访问注入对象的 .Value 属性,否则您甚至不会实例化新的存储库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    相关资源
    最近更新 更多