控制反轉 IOC 與依賴注入 DI

  今天在學習過程中,有一個接觸到IOC 。.netCore中已經幫助開發者實現了IOC 例如:

 
 public class HomeController : Controller
    {
        private ILogger _Logger;

        public HomeController(ILogger logger)  //依賴於抽象,具體細節的實現在IOC容器中實現
        {
            _Logger = logger;
        }
        public IActionResult Index()
        {
            _Logger.LogWarning("測試logger 警告");
            return View();
        }
}
 
//注:如果是自定義的類或者擴展的類,同時要在StartUp的 ConfigureServices方法中註冊一下,才能夠使用。

 

在學習之前先了解幾個概念

DIP           依賴倒置原則
IOC          控制反轉(是一種思想)
DI             依賴注入 實現IOC的一種手段
IOC容器   依賴注入的框架,用來映射依賴 ,管理對象創建和生命週期

那什麼是依賴呢?通俗的講,就是用到的地方。系統中一個類使用了另一個類是非常常見的現象。所以我們不可能完全脫離依賴。

例如在下面的案例中:

public class Person
    {
        public void Speack()
        {
            var china = new ChinaLanguage();
            china.SayHi("小小");
            china.SayBack();
        }
    }


    public class ChinaLanguage
    {
        public string SayHi(string name)
        {
            return $"你好,我是{name}";
        }

        public string SayBack()
        {
            return "我要先離開了";
        }
    }



 public class EnglishLanguage
    {
        public string SayHi(string name)
        {
            return $"hello,I'm{name}";
        }

        public string SayBack()
        {
            return "I'll back";
        }
    }

 public class Main
    {

      public void Excute()
        {
            var person = new Person();
            person.Speack();
        }
    }


 如果我要改成英文版,我就要把Speack 方法修改爲如下:

 
 public void Speack()
        {
            var englishPerson = new EnglishLanguage();
            englishPerson.SayHi("小小");
            englishPerson.SayBack();
        }

 

 如果項目中海油很多地方要使用,我們這樣改起來的工作量比較大,組件之間高度耦合,可擴展性較差,它違背了DIP原則。即高層模塊 Person類,不應該依賴於ChinaSpeack類。下面就看一下依賴倒置原則:

依賴倒置原則:   

  • 1. 上層模塊不應該依賴於下層模塊,它們共同依賴於一個抽象。  
  • 2. 抽象不能依賴於具象,具象依賴於抽象。

按照上面的規則,我們應該將Person 依賴於抽象,而不是具體細節。修改如下:

 
   

    public class Person
    {
        private ILanguage _personSpeack;

        public Person(ILanguage personSpeack)
        {
            _personSpeack = personSpeack;
        }

        public void Speack()
        {
            //var china = new ChinaLanguage();
            //china.SayHi("小小");
            //china.SayBack();
            _personSpeack.SayHi("小小");
            _personSpeack.SayBack();
        }
    }

    public interface ILanguage
    {
        string SayHi(string name);

        string SayBack();
    }

    public class ChinaLanguage:ILanguage
    {
        public string SayHi(string name)
        {
            return $"你好,我是{name}";
        }

        public string SayBack()
        {
            return "我要先離開了";
        }
    }

//調用 public class Main { public void Excute() { var person = new Person(new ChinaLanguage()); //具體細節在外部實現,而不是在類內部調用 person.Speack(); } }

 這樣看來,就把依賴對象的創建和綁定轉移到被依賴對象類的外部來實現了。這樣就實現了控制反轉。(獲得依賴對象的過程被反轉了)

依賴注入的實現方法有三種:

構造函數注入,屬性注入和接口注入。上面的案例就是構造函數注入。

 

講了這麼說的原理,下面稍微記錄一下IOC的缺點,畢竟沒有完美的框架嘛

1.首先在開發的過程中,會需要憑空多很多的接口開發。對於開發而言增加了工作量。

2.IOC 通過反射的方式運行的,在性能上會有一定的損耗。

 

 

參考文檔: https://blog.csdn.net/ivan820819/article/details/79744797

https://www.cnblogs.com/liuhaorain/p/3747470.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章