.NET控制反轉(IOC)和依賴注入(DI)

1、前言
理解這些概念對於我來講有些很是困難。 但實際上它們很是簡單,咱們在平常編碼中使用它。
今天,我想談談編碼中依賴性的問題以及控制反轉(IOC)和依賴注入(DI)想要說些什麼。 本文面向渴望瞭解最重要原則,但在實現方面有點困惑的讀者。服務器

2、疑問點
1. 什麼是控制反轉(IOC)?。
2. 什麼是依賴注入(DI)?。
3. 實現依賴注入的方法
4. 實施這一原則的優勢函數

3、控制反轉IOC
經過下面的例子講解:在咱們大學平常,咱們有時會舉辦各類活動,有時甚至是無聊的講座,考慮並回憶大學的平常生活,讓咱們嘗試將大學和活動與控制反轉(IOC)聯繫起來。測試

   public class College
    {

        private TechEvents _events = null;

        public College()
        {
            _events = new TechEvents();
        }

        public void GetEvents()
        {
            _events.LoadEventDetail();
        }
    }

    public class TechEvents
    {
        public void LoadEventDetail()
        {
            Console.WriteLine("Event Details");
        }
    }

上面 College 類的做用是建立 TechEvents 對象。this

假設我有一個類爲Colleage,另外一個類爲TechEvents。 正如您在上面所看到的,可能會出現許多問題:編碼

  1. 這兩個類彼此緊密耦合。 我不能沒有TechEvents的College,由於在College構造器中建立了一個TechEvents對象。
  2. 若是我對TechEvents進行任何更改,我須要編譯,或者你也能夠說更新College類。
  3. College 控制 Events 的建立。College 知道有組織的單一 Event。 若是有任何特定 event 像足球活動或Party活動被組織,則須要對 College 類進行更改,由於College直接引用Events。spa

  如今我須要以某種方式解決這個問題,不然咱們將沒法在大學裏舉辦任何其餘活動。code

  解決這個問題的方法多是將事件組織的控制權轉移到其餘地方。咱們稱之爲控制反轉(IOC),將控制權轉換爲其餘實體,而不是直接在 College 組織 Event。什麼反轉控制原理說?對象

 換句話說,主要類不該該具備聚合類的具體實現,而應該依賴於該類的抽象。 College類應該依賴於使用接口或抽象類的TechEvents類抽象blog

   /// <summary>
    /// 建立一個接口爲了實現抽象
    /// </summary>
    public interface IEvent
    {
        void LoadEventDetail();
    }

    /// <summary>
    /// 全部類型事件活動類應該實現 IEvent
    /// </summary>
    public class TechEvent : IEvent
    {
        public void LoadEventDetail()
        {
            Console.WriteLine("Technology Event Details");
        }
    }

    /// <summary>
    /// 全部類型事件活動類應該實現 IEvent
    /// </summary>
    public class FootballEvent : IEvent
    {
        public void LoadEventDetail()
        {
            Console.WriteLine("Football Event Details");
        }
    }

    /// <summary>
    /// 全部類型事件活動類應該實現 IEvent
    /// </summary>
    public class PartyEvent : IEvent
    {
        public void LoadEventDetail()
        {
            Console.WriteLine("Party Event Details");
        }
    }

    public class College
    {
        private IEvent _events = null;

        /// <summary>
        /// College 構造器提示說須要一個活動事件
        /// </summary>
        /// <param name="ie"></param>
        public College(IEvent ie)
        {
            _events = ie;
        }

        public void GetEvents()
        {
            _events.LoadEventDetail();
        }
    }

4、依賴注入(DI)索引

      可使用依賴注入(DI)來完成 IOC 。 它解釋了如何將具體實現注入到使用抽象的類中,換句話說就是內部的接口。 依賴注入的主要思想是減小類之間的耦合,並將抽象和具體實現的綁定移出依賴類

簡單來講,DI就是一個對象如何去知道那些被抽象的其餘依賴對象。實現依賴注入主要有4種方法。

一、構造函數注入

  public class College
    {
        private IEvent _events = null;

        /// <summary>
        /// College 構造器提示說須要一個活動事件
        /// </summary>
        /// <param name="ie"></param>
        public College(IEvent ie)
        {
            _events = ie;
        }

        public void GetEvents()
        {
            _events.LoadEventDetail();
        }
    }

如上所示,事件對象由構造函數注入,使其保持抵耦合。 College類將完成他的工做,若是它想獲取與事件相關的詳細信息,它將根據他想要調用的事件在構造函數中調用它。

College coll = new College(new FootballEvent()); 

除了這個優點,另外一個優勢是,若是事件有任何變化或添加了更多事件,那麼College不須要關心這一點。

二、方法注入

class College  
{  
        private IEvent _events;  
        public void GetEvent(IEvent myevent)  
        {  
            this._events = myevent;  
              
        }  
}  

如上所示,我使用GetEvents()方法調用College事件,其中事件類型做爲抽象類型的參數傳遞。 這將幫助我在不影響College 的狀況下添加或更改事件,換句話說,二者都是分離的。 這就是我能夠調用該方法的方法。

College coll = new College();  
coll.GetEvent(new FootballEvent()); 

三、屬性注入

  這是最經常使用的方法,咱們經過建立接口類型的屬性來注入具體類。

class College  
{  
        private IEvent _events;  
        public IEvent MyEvent  
        {  
            set  
            {  
                _events = value;  
            }  
        }  
}  

如上所示,MyEvent屬性的setter將獲取一個具體對象並將其綁定到接口。 個人類與具體的對象低耦合。 如今對任何類型的Event類的任何更改都不會影響個人College類。

College coll = new College();  
coll.MyEvent = new FootballEvent(); 

四、服務器定位注入

  服務定位器能夠像一個簡單的運行時映射器。 這容許在運行時添加代碼而無需從新編譯應用程序,在某些狀況下甚至無需從新啓動它。

 public class College
    {
        private IEvent _events = null;
        EventLocator el = new EventLocator();

        public College(int index)
        {
            _events = el.LocateEvent(index);
        }
    }

    public class EventLocator
    {
        public IEvent LocateEvent(int index)
        {
            if (index == 1)
            {
                return  new FootballEvent();
            }
            else if(index == 2)
            {
                 return  new PartyEvent();
            }
            else
            {
                return  new TechEvent();
            }
        }
    }

在上面的代碼片斷中,您能夠看到 Events 和 College 之間有一個EventLocator類,它能夠幫助咱們在不知道具體類型的狀況下找到服務。 我只是在構造函數中傳遞索引值,而構造函數又調用第三方來定位事件並將其返回給構造函數。 所以,對EventLocator的任何更改都不會影響College類。

College coll = new College(1);  
coll.GetEvents();  

實時上述原則的優勢:

一、它有助於類的解耦。
二、因爲解耦,代碼的可重用性增長。
三、改進了代碼可維護性和測試。

5、總結

   控制反轉(IOC)討論了誰將啓動調用,其中依賴注入(DI)討論一個對象如何經過抽象獲取對其餘對象的依賴。

 

這邊文章主要引用國外網友的文章,如有以爲有不合理之處,能夠查看原文 :https://www.c-sharpcorner.com/UploadFile/cda5ba/dependency-injection-di-and-inversion-of-control-ioc/

相關文章
相關標籤/搜索