C# 全局与依赖注入

C# 全局与依赖注入,c#,C#,有人说使用依赖注入更好。为什么呢 我认为最好少一些全局的、易于访问的类,而不是庞大的构造函数 它是否以任何方式影响应用程序速度 这两者的结合可能是最好的。您可能会使用静态类和方法作为全局变量。它们对性能没有任何影响。但是,静态类不适合测试性 此外,一旦您的代码与静态类Globals紧密耦合,您将无法在将来用替代实现替换它们。因此,除非在非常简单的情况下使用Globals,否则Globals可能不是一个好的设计 注意,静态类和方法是编译时绑定,而as DI是运行时绑定。帮助您保持类的松散耦合。主要

有人说使用依赖注入更好。为什么呢

我认为最好少一些全局的、易于访问的类,而不是庞大的构造函数

它是否以任何方式影响应用程序速度


这两者的结合可能是最好的。

您可能会使用静态类和方法作为全局变量。它们对性能没有任何影响。但是,静态类不适合测试性

此外,一旦您的代码与静态类Globals紧密耦合,您将无法在将来用替代实现替换它们。因此,除非在非常简单的情况下使用Globals,否则Globals可能不是一个好的设计


注意,静态类和方法是编译时绑定,而as DI是运行时绑定。帮助您保持类的松散耦合。

主要优势是解耦,这将有助于单元测试。这完全取决于如何编写这些易于访问的类

想法是这样的。一个类只依赖于契约接口,从而与实现类的依赖性分离。在您的实时环境中,您可能永远不会提供新的实现类,但在您的测试环境中,您很可能是一个手工制作的存根,或者是来自模拟框架的模拟类


应用程序速度需要分析,但是使用DI框架可能会产生一些开销,而不是直接与您所知道的单例进行交谈。重要的问题是:这是一个开销问题吗?只有性能期望和分析才能告诉您这一点。根据我的经验,其好处远远大于可忽略的性能损失。

使用globals和DI之间存在巨大差异。首先,路径通常是不直接的,因为您可能会通过和。如今,这两种模式都被视为反模式。原因是我们应该设计可测试的代码,当我们需要更改代码库以进行维护或满足新需求时,这给了我们巨大的优势。如果代码是解耦的,那么很容易实现可测试性。正如您猜测的那样,全局行为无助于解耦,因此,例如,如果您的代码加入了静态单例,要测试这样的代码,您需要单例本身,您不能模拟它,这是不好的,因为您不能随心所欲地对系统施加压力。服务定位器乍一看似乎更好:如果需要测试,您可以模拟服务定位器,但您必须:

提前知道被测系统将向定位器询问哪些服务 始终创建递归模拟,因为您可能也会模拟返回的服务。
构造函数上的DI是代码解耦的一种好方法,因为您可以非常清楚地说明对象需要运行什么,并且您可以一目了然地决定要模拟什么、存根等等。请注意,如果您确保不让DI内核作为依赖项在您的代码中运行,DI将起作用并帮助您:这将在反模式中转换DI您将代码解耦,但您将其绑定到容器,因此请记住学习并真正实现c,这将帮助您编写更好的可测试代码

我认为这篇主题的头条文章对DI以及如何正确使用DI进行了很好的总结:


如果您想深入探讨这个主题,我可以推荐Mark Seeman的《.NET中的依赖注入》一书。

如果您使用的是基于构造函数的DI,发现有一个类的构造函数接受了很多参数,这可能表明这个类做了太多不相关的事情,应该被分成多个类。请参阅关注点分离。大多数框架都不需要您实际使用构造函数,而通常是使用构造函数。解决和配置您的依赖项(已事先组合好)由框架注入。