关于依赖注入的理解

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();
 }
View Code

     类定义ElectricPowerSwitch:

      

ISwitch
View Code

    具体应用,实现类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();

 

posted on 2025-02-26 11:17  博观约取*厚积薄发  阅读(21)  评论(0)    收藏  举报