理解依賴注入(IOC)和學習Unity

2021-07-13 13:20:04 字數 3880 閱讀 9982

ioc:英文全稱:inversion of control,中文名稱:控制反轉,它還有個名字叫依賴注入(dependency injection)。

作用:將各層的物件以松耦合的方式組織在一起,解耦,各層物件的呼叫完全面向介面。當系統重構的時候,**的改寫量將大大減少。

理解依賴注入:

當乙個類的例項需要另乙個類的例項協助時,在傳統的程式設計過程中,通常有呼叫者來建立被呼叫者的例項。然而採用依賴注入的方式,建立被呼叫者的工作不再由呼叫者來完成,因此叫控制反轉,建立被呼叫者的例項的工作由ioc容器來完成,然後注入呼叫者,因此也稱為依賴注入。

舉個有意思的例子(**於網際網路)

假如我們要設計乙個girl和乙個boy類,其中girl有kiss方法,即girl想要kiss乙個boy,首先問題是girl如何認識boy?

在我們中國常見的mm認識gg的方式有以下幾種:

a 青梅竹馬    b 親友介紹   c 父母包辦

哪一種是最好的?

1.青梅竹馬:很久很久以前,有個有錢的地主家的一閨女叫lily,她老爸把她許配給縣太爺的兒子jimmy,屬於指腹為婚,lily非常喜歡kiss,但是只能kiss jimmy

public class lily  

public void kiss()

} public class jimmy

}

這樣導致lily對jimmy的依賴性非常強,緊耦合。

2.親友介紹:經常kiss同乙個人令lily有些厭惡了,她想嘗試新人,於是與jimmy分手了,通過親朋好友(中間人)來介紹

public class lily  

public void kiss()

}

親友介紹,固然是好。如果不滿意,儘管另外換乙個好了。但是,親友boyfactory經常是以singleton的形式出現,不然就是,存在於globals,無處不在,無處不能。實在是太繁瑣了一點,不夠靈活。我為什麼一定要這個親友摻和進來呢?為什麼一定要付給她介紹費呢?萬一最好的朋友愛上了我的男朋友呢?

3.父母包辦:一切交給父母,自己不用非吹灰之力,lily在家只kiss

public class lily  

public void kiss()

}

well,這是對girl最好的方法,只要想辦法賄賂了girl的父母,並把boy交給他。那麼我們就可以輕鬆的和girl來kiss了。看來幾千年傳統的父母之命還真是有用哦。至少boy和girl不用自己瞎忙乎了。這就是ioc,將物件的建立和獲取提取到外部。由外部容器提供需要的元件。

在設計模式中我們應該還知道依賴倒轉原則,應是面向介面程式設計而不是面向功能實現,好處是:多實現可以任意切換,我們的boy應該是實現kissable介面。這樣一旦girl不想kiss可惡的boy的話,還可以kiss可愛的kitten和慈祥的grandmother

好在.net中微軟有乙個輕量級的ioc框架unity,支援構造器注入,屬性注入,方法注入如下圖所示

具體使用方法如下圖所示

using system;  

using microsoft.practices.unity;

} public inte***ce ikiss

public class lily:ikiss

public void kiss()

} public class boy : ikiss

} }

如果採用配置檔案註冊的話

<?xml version="1.0" encoding="utf-8" ?>  

配置的後台**:

unityconfigurationsection configuration = configurationmanager.getsection(unityconfigurationsection.sectionname)  

as unityconfigurationsection;

configuration.configure(container, "defaultcontainer");

可以通過方法resolveall來得到所有註冊物件的例項:

var instances = container.resolve();

martin fowler在那篇著名的文章《inversion of control containers and the dependency injection pattern》中將具體依賴注入劃分為三種形式,即構造器注入、屬性(設定)注入和介面注入,習慣將其劃分為一種(型別)匹配和三種注入:

我們建立乙個控制台程式,定義如下幾個介面(ia、ib、ic和id)和它們各自的實現類(a、b、c、d)。在型別a中定義了3個屬性b、c和d,其型別分別為介面ib、ic和id。其中屬性b在構在函式中被初始化,以為著它會以構造器注入的方式被初始化;屬性c上應用了dependencyattribute特性,意味著這是乙個需要以屬性注入方式被初始化的依賴屬性;屬性d則通過方法initialize初始化,該方法上應用了特性injectionmethodattribute,意味著這是乙個注入方法在a物件被ioc容器建立的時候會被自動呼叫。

public inte***ce ia   

public inte***ce ib

public inte***ce ic

public inte***ce id

public class a : ia

[dependency]

public ic c

public id d

public a(ib b)

[injectionmethod]

public void initalize(id d)

} public class b : ib

public class c : ic

public class d : id

然後我們為該應用新增乙個配置檔案,並定義如下一段關於unity的配置。這段配置定義了乙個名稱為defaultcontainer的unity容器,並在其中完成了上面定義的介面和對應實現類之間對映的型別匹配。

<?xml version="1.0" encoding="utf-8" ?>  

最後在main方法中建立乙個代表ioc容器的unitycontainer物件,並載入配置資訊對其進行初始化。然後呼叫它的泛型的resolve方法建立乙個實現了泛型介面ia的物件。最後將返回物件轉變成型別a,並檢驗其b、c和d屬性是否是空

class program  

",a.b==null?"yes":"no");

console.writeline("a.c==null?", a.c == null ? "yes" : "no");

console.writeline("a.d==null?", a.d == null ? "yes" : "no");

} }

}

從如下給出的執行結果我們可以得到這樣的結論:通過resolve方法返回的是乙個型別為a的物件,該物件的三個屬性被進行了有效的初始化。這個簡單的程式分別體現了介面注入(通過相應的介面根據配置解析出相應的實現型別)、構造器注入(屬性b)、屬性注入(屬性c)和方法注入(屬性d)

a.b == null ? no
a.c == null ? no
a.d == null ? no

理解依賴注入(IOC)

ioc 英文全稱 inversion of control,中文名稱 控制反轉,它還有個名字叫依賴注入 dependency injection 作用 將各層的物件以松耦合的方式組織在一起,解耦,各層物件的呼叫完全面向介面。當系統重構的時候,的改寫量將大大減少。理解依賴注入 當乙個類的例項需要另乙個...

ioc(依賴 依賴倒置 依賴注入)

先看一下這個大佬的部落格 我只是畫個圖 1.依賴 這個很不友好,要換別的player或者meidafile要動operation 2.依賴倒置 這個好很多了,加了兩個介面,要換別的player或者meidafile,不用動operation 3.ioc 控制反轉 控制權是我們使用者自己,如果是spr...

Spring 學習筆記 IOC 依賴注入

簡述 spring 學習 ioc 依賴注入 1 直接使用原始類建立bean 2 使用工廠方法建立bean 3 使用工廠類建立bean 1 setter injection 2 constructor injection 建構函式注入 1 inner beans 2 collections map 3...