1. 程式人生 > 程式設計 >Spring.Net IOC依賴注入原理流程解析

Spring.Net IOC依賴注入原理流程解析

一。什麼是IOC.(Inversion of Control)

  IOC,即控制反轉。不是什麼技術,而是一種思想。在傳統開發中,我們需要某個物件時,就手動去new一個依賴的物件。而IOC意味著將物件的控制權交給容器,而不在是直接在物件的內部控制。如何理解IOC呢?理解好IOC的關鍵是要明確‘誰控制了誰,控制了什麼?為何是反轉?(有反轉既有正轉),哪些反面反轉了。'

誰控制了誰?控制了什麼?:傳統程式設計,我們直接在物件內部通過new來建立物件,是程式主動去建立物件。而在ioc中,是通過一個容器去建立這些物件,即IOC容器控制物件的建立;誰控制了誰?當然是IOC容器建立了物件;控制了什麼?當然是控制了外部資源的獲取。(不只是物件,比如包括檔案等)

為何是反轉?哪些方面反轉了?:有反轉就有正轉。傳統應用程式由我們自己在物件中主動獲取建立依賴物件,也就是正轉;而反轉則是由容器來建立及注入依賴物件。為什麼是反轉呢?因為由容器幫我們查詢及注入依賴,物件只是被動的接受依賴物件,所以是反轉。哪些方面反轉了?依賴物件的獲取被反轉了。

圖列說明

圖一. 傳統程式設計,主動建立相關物件,再組合起來

Spring.Net IOC依賴注入原理流程解析

圖二。當有了IOC/DI容器之後,客戶端不在主動建立這些物件

Spring.Net IOC依賴注入原理流程解析

二。iOC能夠做什麼?

  IOC是一種思想,而不是新的技術。一個重要的面向物件程式設計的法則,它能指導我們如何設計出鬆耦合,更優良的程式。傳統的應用程式都是我們在類的內部,主動的建立應用物件,從而導致類與類之間,高耦合,難於測試。有了IOC容器,就將查詢和建立依賴物件的控制交給了容器,由容器進行注入組合物件,所以物件與物件之間,是鬆散耦合的,使得程式的整個體系結構變得非常靈活。

  其實IOC對程式設計帶來最大的變化,不是從程式碼上的,而是思想上,發生了‘主從換位'的變化。應用程式原本是老大,需要什麼資源,都是主動去獲取。但是在IOC/DI中,應用程式變成了被動了,被動的等待容器來建立並注入它所需要的資源。

  IOC很好的體現了面向物件設計原則,好萊塢法則:“別找我們,我們找你”。即由IOC容器幫物件去找依賴的物件,並注入,而不是由物件主動去找。

三。IOC和DI

  DI(Dependency Injection),即依賴注入。是元件之間的關係由容器在在執行期確定,形象的說,即由容器動態的將某個依賴關係注入到元件之中。依賴注入的目的並非為軟體系統帶來更多功能,而是為了提升元件重用的頻率,併為系統搭建一個靈活、可擴充套件的平臺。通過依賴注入機制,我們只需要通過簡單的配置,而無需任何程式碼就可指定目標需要的資源,完成自身的業務邏輯,而不需要關心具體的資源來自何處,由誰實現。

理解DI的關鍵是:‘誰依賴了誰,為什麼需要依賴,誰注入了誰,注入了什麼':

誰依賴了誰:當然是應用程式依賴了容器為什麼需要依賴:應用程式需要IOC容器提供物件所需要的資源誰注入了誰:很明顯是IOC容器注入應用程式某個物件,應用程式依賴的物件注入了什麼:就是注入某個物件所需要的外部資源(包括物件,資源,檔案,常量資料)  

  IOC和DI之間,是同一個概念不同角度的描述。相對於IOC而言,“依賴注入“明確描述” 被注入物件依賴IOC容器配置依賴物件”。

四 。Spring.Net之IOC的配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler,Spring.Core"/>
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler,Spring.Core" />
    </sectionGroup>
  </configSections>
  <spring>
    <context>
      <!--載入容器所需的配置檔案,預設是config檔案.這裡單獨定義一個檔案xml,來配置容器.需要注意的是,xml檔案屬性需要設定為始終複製或如果較新規則複製-->
      <resource uri="config://spring/objects"/>
      <resource uri="F:\\C#\\SpingNetIOCV2\\ioc\\ioc.xml"/>
    </context>
    <objects xmlns="http://www.springframework.net">
      <!--<object name="myIoc" type="SpingNetIOCV2.model.Moveis,SpingNetIOCV2"></object>-->
    </objects>
  </spring

ioc.xml程式碼段配置如下:

<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <object name="myIoc" type="SpingNetIOCV2.model.Moveis,SpingNetIOCV2"></object>
</objects>

控制檯程式main方法中,引用Spring.Context命令空間,以便IApplicationContext介面訪問IOC容器。,下面通過容器,獲取一個建立的物件:

public static void Main(string[] args)
    {
      //獲取容器物件
      IApplicationContext context = ContextRegistry.GetContext();
      //通過容器建立物件
      Moveis m =(Moveis)context.GetObject("myIoc");
      Console.WriteLine(m.GetType().Name);//結果輸出Moveis
      Console.ReadKey();
    }

A。通過屬性注入依賴物件 

<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <!--MovieLister物件,依賴SimpleMovieTXTFinder獲取對應的電影資源-->
  <object name="myIoc" type="SpingNetIOCV2.model.MovieLister,SpingNetIOCV2">
    <property name="move" ref="SimpleMovieTXTFinder"></property>
  </object>
  <!--SimpleMovieTXTFinder類是載入獲取儲存在txt文字中的電影資訊工具類-->
  <object name="SimpleMovieTXTFinder" type="SpingNetIOCV2.model.SimpleMovieTXTFinder,SpingNetIOCV2"></object>
</objects>
public static void Main(string[] args)
    {
      //獲取容器物件
      IApplicationContext context = ContextRegistry.GetContext();
      //通過容器建立物件
      //Moveis m =(Moveis)context.GetObject("myIoc");
      //通過屬性注入(set值方法注入)。物件MovieLister依賴IMoveis,通過容器建立依賴物件,注入到物件MovieLister的move屬性中
      //容器先建立MovieLister物件,看MovieLister類是否需要注入。如果需要注入,則建立所需的依賴物件SimpleMovieTXTFinder,然後通過屬性。注入到MovieLister物件中
      MovieLister ml = (MovieLister)context.GetObject("myIoc");
      Console.WriteLine(ml.GetType().Name);//結果輸出MovieLister
      ml.GetMoves(1);
      Console.ReadKey();
    }

B。構造器注入依賴

<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <!--MovieLister物件,依賴SimpleMovieTXTFinder獲取對應的電影資源-->
  <object name="myIoc" type="SpingNetIOCV2.model.MovieLister,SpingNetIOCV2">
    <!--<constructor-arg/>節點就是用來為構造器提供引數的IoC容器使用某個內建的型別轉換器將字串“move.txt”轉換為System.IO.FileInfo-->
    <constructor-arg index="0" value="../../move.txt"/>
  </object>
</objects>

文字move.text是電影文字列表,IOC容器通過構造器注入,將外部資源注入到了MovieLister物件中。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。