【问题标题】:ASP.Net MVC Controller injectionASP.Net MVC 控制器注入
【发布时间】:2025-12-29 02:45:10
【问题描述】:

我正在寻找有关设计新 ASP.NET Mvc 项目的好方法的建议。它中等大小,结构相对简单。我最初使用 Spring.Net 将我的服务对象连接到正确的构造函数中,但现在管理层告诉我 Spring.Net 或任何其他 IOC 容器不能在我们的环境中使用。

在没有 DI 的情况下,我很难找到一种设置它的好方法。我希望能够以允许控制器和服务之间的少量耦合并尽可能限制控制器对单个服务实现的可靠性的方式将服务实现分配给控制器。我想我的问题归结为一个事实,即我不确定我应该在 MVC 模型中手动连接我的应用程序的位置。

有什么建议吗?

【问题讨论】:

  • 我很好奇为什么管理层规定你不能使用 DI?管理层为开发人员做出这种性质的技术决策是否正常?如果是这样...运行。
  • 这是一个很好的问题,我不确定,这里的其他一些开发人员并不真正熟悉这个概念,也不想尝试,所以管理层支持他们暂时。
  • 由于托管扩展框架 (mef.codeplex.com) 是 .Net 的一部分,同样的限制是否适用?
  • 使用像 ninject 这样的依赖注入框架使 DI 变得微不足道。也许您应该与团队和高层管理人员重新讨论这个话题?
  • @zaq:在这种情况下,跟随团队的领导者,不要强迫团队冲突。但是,只要可以,请根据自己的(最高)标准设计和编写您制作的代码。换句话说,考虑到依赖注入(即使用糟糕的 mans DI),并通过单元测试支持您的代码。这样,您将尽自己的一份力量来编写好的软件。换句话说,以身作则。时机成熟时,请仔细激励您的队友和团队领导深入研究 DI。我同意团队负责人的观点,即 DI 感觉很复杂(起初),但它非常值得付出努力。

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


【解决方案1】:

由于您使用的是 ASP.NET MVC 3,因此您可以编写 custom dependency resolver。当然,你仍然会设计你的控制器,在它们的构造函数中使用接口,以削弱层之间的耦合。然后在自定义依赖解析器中,为了满足强加给您的荒谬要求,您将不得不手动说,当您拥有ISomeService 时,您将返回SomeServiceImpl 的实例。你知道,对象容器和 DI 框架已经为你做的事情。所以你基本上必须重新发明一些*。顺便说一句,Ayende 曾在博客上写过 build a custom IoC container in 15 lines of code 的方法,但当然这不是你应该做这样的事情的理由。

提出此类要求的人应该面临审判,并被判处永远不必接触应用程序设计。强加这样的要求说明在设计应用程序中完全缺乏关于良好实践的知识。在对公司造成进一步损害之前,应告知这些人。

所以简单地向那些人解释一下,通过重新发明*有两个错误:

  • 你会在别人已经做过的事情上浪费很多时间
  • 您会犯错误,因为您不会考虑其他人设计可重用 DI 框架时考虑的所有边缘情况。

最终,您将延迟交付应用程序(因为您会浪费时间编写管道代码),更糟糕的是,您将交付包含潜在错误的应用程序。

结论:昂贵且有缺陷的产品。你的管理层一定是真的疯了:-)

结论2:使用现有的DI框架。管理层甚至不会注意到,因为他们似乎不了解通过施加此类要求来了解应用程序的技术方面。

【讨论】:

  • 我同意你的观点,我试图解释这些问题(也许我解释得不好),但担心其他开发人员获取这些概念所需的时间不会值得,而且可能很难聘请熟悉特定框架的新开发人员。
  • @zaq,您认为通过滚动自定义 DI 框架来重新发明*所浪费的时间值得吗?如果开发人员无法通过阅读数以百万计的教程来掌握现有 DI 框架的概念,那么相信我,掌握具有自定义依赖解析器的自定义构建 DI 框架的概念将更加重要。
  • 哦,我完全同意,但不幸的是,需要说服的不是我。
  • 我只是希望有人知道如何在不直接在控制器中创建新服务对象或在所有服务中声明工厂/单例方法(没有 IOC)的情况下实现这一点。跨度>
  • @zaq,在我的回答中,我建议您使用控制反转,并让您的控制器的构造函数仅采用接口。具体类型的实际实例化将在您的自定义依赖解析器中完成。您永远不会直接在控制器中创建任何新的服务对象。您的控制器看起来与使用 DI 框架完全相同。
【解决方案2】:

首先,我会质疑为什么管理层要求您不能使用允许您实现松散耦合和依赖注入的模式和工具。这是可以讨论和推理的吗?

对于 IoC 容器,实现一个 IControllerFactory 从容器中解析控制器并注入必要的服务是微不足道的。

在 MVC 3 中,您可以使用 IDependencyResolver 实现比直接在控制器内部实例化服务稍微松散的耦合(通过服务定位器模式/反模式);这个接口被设计为与 IoC 容器一起使用,但实际上它本身就是一个较差的替代品。

【讨论】:

  • 我对此进行了研究并开始使用它,但似乎我最终只会编写自己的半 DI 容器,这是一个坏主意。我会从你对我原来帖子的评论中接受你关于“可怜的人 DI”的建议。它仍然不是一个很好的解决方案,但我认为考虑到我的限制,这是唯一的选择。感谢您的帮助。
【解决方案3】:

你的老板有尖头发吗? http://www.dilbert.com/

您可以通过使用http://unitymvc3.codeplex.com/ 而不是编写自己的自定义依赖解析器来节省一些时间。可通过 Nuget http://nuget.org/ 下载。如果你使用这样的 IOC 容器,并使用构造函数注入,你会发现你的单元测试更容易编写。这是假设您的经理相信单元测试 ;-) 祝你好运!

【讨论】:

  • 它看起来不错,但不幸的是我已经建议将 Unity 作为 Microsoft 的 Spring 替代品。
  • 它的设置和使用非常简单(专门用于将 Unity 与 MVC3 结合使用),不需要任何特殊配置,并且对于您的团队成员而言,学习曲线将是最小的。不过祝你好运,听起来你可能需要它;-)
  • 谢谢托尼,也许我会看看这个再试一次。
【解决方案4】:

管理层告诉我 Spring.Net 或任何其他 IOC 容器是 不要在我们的环境中使用。

管理层告诉您,不允许您编写松散耦合、可测试和高度可维护的应用程序,这就是他们告诉您的。这是一个奇怪的限制。

依赖注入是许多开发人员不了解的高级技术。但是,管理层永远不会理解它,理解它也不是他们的工作。他们可能会规定技术的类型(例如 .NET 与 Java),因为这会影响他们需要雇用的人员类型,但是当他们开始规定阻止您编写下降软件的低级实施细节时,您的公司就会走向灾难。

现在就可以离开那家公司了!

您的另一个选择是使用Simple Injectorsource code。代码库足够小(大约 500 行,只需使用 SimpleInjector.NET 项目)能够将其复制到本地项目(并且许可证允许)。这样它就是你自己的本地 DI 容器,但经过全面测试:-)

祝你好运。

【讨论】:

    【解决方案5】:

    你需要一个新家。有很多组织正在寻找关心质量和可扩展架构的优秀工程师。确保您找到合适的人,他们会很高兴找到您。

    避免让您当前的团队摆脱短视的诱惑。从你的描述来看,尽管你有才华,但听起来你已经是一个贱民了。接受你不会被倾听的事实。

    最好的策略是假装成为一个重生的团队成员。完全按照你老板的要求构建你的 MVC 项目,即愚蠢的方式,没有关注点分离。当您的项目的第 1 版完成并通过 QA(如果您有任何 QA)时,您的老板可能会认为他是正确的。为这个反应做好准备。

    启发当前团队成员的最大希望是向他们展示即使您使用他们熟悉的相同愚蠢做法构建软件,您仍然可以围绕他们运行。这可能很有趣。然后,当你离开时,你给他们一个机会来反思你做某事的可能性。他们可以抓住这个机会,也可以选择继续舒适,但这将不再是您的问题。

    【讨论】:

      最近更新 更多