- 因为本人是.NET开发,下列文章以及例子都是在C#的基础上理解以及展开。
1.依赖注入简介
依赖注入:(Dependency Injection,简称DI)是一种设计模式,它的核心思想是将对象依赖的外部资源(如其他对象或服务)从对象内部创建,转移到外部来处理,从而降低耦合度(即降低不同组件、模块或类之间的相互依赖性),提高代码可测试性和可维护性。
耦合度(简单说明):软件工程中的一个重要概念,指的是不同组件、模块或类之间的相互依赖性、关联性。
2.简单的依赖注入的例子
假设有一个Ikun
接口和两个其实现类:
public interface IKun
{
void SingDanceRap(string music);
}
// 第一个服务实现-梳中分
public class ZhongFen: IKun
{
public void SingDanceRap(string music)
{
Console.WriteLine($"梳中分,唱跳Rap:{music}");
}
}
// 第二个服务实现-穿背带裤
public class BeiDaiKu : IKun
{
public void SingDanceRap(string music)
{
Console.WriteLine($"穿背带裤,唱跳Rap:{music}");
}
}
// 客户端类,原本直接依赖于某种服务
public class PlayBasketball
{
private readonly IKun _kun;
// 传统做法是在这里直接new一个具体的类
// public PlayBasketball()
// {
// _kun = new ZhongFen();
// }
// 使用依赖注入的做法,构造函数注入
public PlayBasketball(IKun kun)
{
_kun = kun;
}
public void BasketballPlay(int number)
{
string message = $"再看{number}眼就会爆炸";
_kun.SingDanceRap(message);
}
}
在没有使用依赖注入的情况下,PlayBasketball可能会直接在构造函数中创建并初始化ZhongFen实例。但这样一来,PlayBasketball就与具体的ZhongFen耦合了。
依赖注入的实现:
1.常规实现
通过构造函数注入,我们可以在应用程序启动时或通过IoC容器来注入所需的依赖项,如下所示:
// 使用构造器注入来创建PlayBasketball实例
var beiDaiKu = new BeiDaiKu();
var playBasketball = new PlayBasketball(beiDaiKu);
playBasketball.BasketballPlay(1); // 这里会调用BeiDaiKu来发送消息
//输出:"穿背带裤,唱跳Rap:再看1眼就会爆炸"
2.ASP.NET Core框架
如果是ASP.NET Core这样的框架,可以利用其内置的依赖注入容器:
//在Startup.cs文件中配置依赖注入服务:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// 将IKun的实现BeiDaiKu注册到服务容器中
services.AddSingleton<IKun, BeiDaiKu>();
// 其他服务配置...
services.AddControllers();
}
}
-
1.第一种实现
- MyController直接依赖于IKun接口,并在其BeiDaiKu方法内直接调用唱跳Rap方法来发送消息。
-
// 第一种实现 // 在控制器中通过构造函数注入使用已注册的服务: public class MyController : Controller { private readonly IKun _kun; public MyController(IKun kun) { _kun = kun; } [HttpGet] public IActionResult Play(string music) { //外部接口调用传入music,执行背带裤方法 _kun.SingDanceRap(music); //假如入参是"你干嘛哎呦",则输出:"穿背带裤,唱跳Rap:你干嘛哎呦" return Ok(); } }
-
2.第二种实现
- MyController依赖于PlayBasketball,并通过注入的PlayBasketball实例间接调用IKun来处理和发出消息。
-
// 第二种实现 // 在需要的地方注入PlayBasketball public class MyController : Controller { private readonly PlayBasketball _playBasketball; public MyController(PlayBasketball playBasketball) { _playBasketball = playBasketball ; } public IActionResult Play(int number) { _playBasketball.BasketballPlay(number); // 假如入参是1,则输出:"穿背带裤,唱跳Rap:再看1眼就会爆炸" return Ok(); } }
按照通常的ASP.NET Core应用程序配置,且相应的服务已经在服务容器中正确注册,那么这两个类都会通过框架的依赖注入机制正确工作。
如果我们需要切换服务,只需更改配置,而无需修改PlayBasketball或MyController的任何代码,大大增强了代码的可扩展性和可维护性。