关于依赖注入的理解
1 依赖倒置
1.1 代码耦合与避免
使用new关键字在一个类中创建另一个类的对象时,会造成耦合;或者说高层次的类依赖低层次的类,当高层次的类应用需求发生变化时,就会造成麻烦。
例如,有一个开关类Switch和灯类LightBulb, LightBulb有两个方法TurnOn()各TurnOff,开关类有一个按键方法Press(); 如果在Switch类内创建LightBulb对象,或者将LightBulb对象传递给Switch;那么,当Switch需要控制其他电器时,就必须改写Switch类的实现,由此造成了耦合。
解决方法是:定义接口功能,定义Switch时,参数定义成接口,定义为抽象;实现时,传递实现接口的对象。当需要控制其他电器时,定义一个新电器类,并将新电器类的实例对象传递给Switch就可以了。
定义开关接口ISwitch:
internal interface ISwitch
{
bool IsOn();
void Press();
}
定义装置接口IAppliance:
internal interface IAppliance { public void turnOn(); public void turnOff(); }
定义电器开关类ElectricPowerSwitch:
public class ElectricPowerSwitch: ISwitch { readonly IAppliance _lightBulb; bool _isOn; internal ElectricPowerSwitch(IAppliance lightBulb) { _lightBulb = lightBulb; _isOn = false; } public bool IsOn() { return _isOn; } public void Press() { bool checkOn = IsOn(); if (checkOn) { _lightBulb.turnOff(); _isOn = false; } else { _lightBulb.turnOn(); _isOn = true; } } }
定义灯泡类LightBulb:
internal class LightBulb: IAppliance { public void turnOn() { Console.WriteLine("LightBulb: Bulb turned on..."); } public void turnOff() { Console.WriteLine("LightBulb: Bulb turned off..."); } }
定义风扇类Fan:
internal class Fan : IAppliance { public void turnOff() { Console.WriteLine("Fan is turnoff"); } public void turnOn() { Console.WriteLine("Fan is turnon"); } }
调用:
IAppliance ap = new LightBulb(); ISwitch swt = new ElectricPowerSwitch(ap); swt.Press(); ap = new Fan(); swt = new ElectricPowerSwitch(ap); swt.Press();
使用依赖倒置原则,写出松耦合的代码;一个类确切知道另一个类的设计和实现,一个类的变化必然引起另一个类的变化,这种情况就是紧耦合,写出的代码就脆弱,弹性不够。
高层次的模块不应该依赖低层次的模块。
小结:
1 编程尽量打破依赖关系,使用程序更具有弹性。
2 尽量打破依赖关系,面向接口设计类,将公用方法抽向为接口方法,类继承接口,负责具体实现。
3 调用时,定义结构,用类实例化。
2 依赖注入
2.1 依赖注入表示代码功能如何工作
2.2 依赖注入举例
接口定义IAppliance:
internal interface IAppliance { public void turnOn(); public void turnOff(); }
接口定义ISwitch:
internal interface ISwitch { bool IsOn(); void Press(); }
类定义ElectricPowerSwitch:
ISwitch
具体应用,实现类ElectricPowerSwitch对类LightBulb的依赖注入。
IAppliance ap = new LightBulb(); ISwitch swt = new ElectricPowerSwitch(ap); swt.Press();
2.3 DI容器
在现实应用中,有许多类,存在较多依赖关系;需要一个DI容器,进行配置,它知道什么类型,负责自动创建并管理对象,通常称为服务。
3 使用依赖注入的步骤
//1 创建服务容器:ServiceCollection var serviceCollection = new ServiceCollection(); //2 注册服务:将定义好的类加入容器 serviceCollection.AddSingleton<Fan>(); serviceCollection.AddSingleton<IAppliance, Fan>(); //3 从服务集合构建服务提供者 ServiceProvider prv = serviceCollection.BuildServiceProvider(); //4 获取需要的服务 var fanService = prv.GetService<Fan>(); //5 使用服务 fanService.turnOn();
浙公网安备 33010602011771号