解释 C# 中的依赖注入
csharpserver side programmingprogramming
依赖项是另一个对象所依赖的对象。依赖注入(或反转)基本上是提供对象所需的对象,而不是让对象自己构造对象。这是一种有用的技术,可以使测试更容易,因为它允许您模拟依赖项。
例如,如果类 A 调用类 B 上的方法,而类 B 又调用类 C 上的方法,则意味着 A 依赖于 B,而 B 依赖于 C。使用依赖注入,我们可以将类 C 的实例传递给类 B,并将类 B 的实例传递给类 A,而不是让这些类构造 B 和 C 的实例。
在下面的示例中,类 Runner 依赖于类 Logger。请注意,类 Runner 在构造函数中创建了 Logger 的实例。这段代码有几个问题。
这将 logger 类与 Runner 绑定在一起,如果不修改 Runner,我们就无法用其他类替换它。
如果 Logger 有任何依赖项,则 Worker 必须在实例化 Logger 之前配置它们。
测试更加困难。如果 Logger 是资源密集型类,例如访问网络或文件系统,它将减慢测试速度。我们无法轻松替换它。
using System; class Program{ static void Main(string[] args){ var runner = new Runner(); runner.Run(); } } class Runner{ private Logger _logger; public Runner(){ _logger = new Logger(); } public void Run(){ // 做一些工作 _logger.Log("要记录的消息"); } } class Logger{ public void Log(string message){ Console.WriteLine(message); } }
使用依赖注入,我们修改 Runner 的构造函数以接受接口 ILogger,而不是具体对象。我们更改 Logger 类以实现 ILogger。这允许我们将 Logger 类的实例传递给 Runner 的构造函数。这样做的好处是,在测试期间,我们可以创建一个实现 ILogger 的 TestLogger 类并将其传递给 Runner 的构造函数。
示例
using System; class Program{ static void Main(string[] args){ var logger = new Logger(); var runner = new Runner(logger); runner.Run(); } } class Runner{ private ILogger _logger; public Runner(ILogger logger){ _logger = logger; } public void Run(){ // 做一些工作 _logger.Log("Message to be logged"); } } interface ILogger{ void Log(string message); } class Logger : ILogger{ public void Log(string message){ Console.WriteLine(message); } }
输出
Message to be logged