日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

三、依赖注入是什么?

發(fā)布時(shí)間:2024/4/17 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 三、依赖注入是什么? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

接口

在說(shuō)依賴(lài)注入之前,先了解下什么是接口。

我們?cè)趯W(xué)編程的時(shí)候都知道,接口的相關(guān)規(guī)則:來(lái)源百度百科

  • 1. 接口是一個(gè)引用類(lèi)型,通過(guò)接口可以實(shí)現(xiàn)多重繼承。
  • 2. C#中接口的成員不能有new、public、protected、internal、private等修飾符。
  • 3. 接口中只能聲明"抽象"成員(所以不能直接下一步對(duì)接口進(jìn)行實(shí)例化(即不能使用new操作符聲明一個(gè)接口的實(shí)例對(duì) 象)),而不能聲明共有的域或者私有的成員變量。
  • 4. 接口聲明不包括數(shù)據(jù)成員,只能包含方法、屬性、事件、索引等成員。
  • 5. 接口名稱(chēng)一般都以“I”作為首字母(當(dāng)然不這樣聲明也可以),這也是接口和類(lèi)的一個(gè)區(qū)別之一。
  • 6. 接口成員的訪問(wèn)級(jí)別是默認(rèn)的(默認(rèn)為public),所以在聲明時(shí)不能再為接口成員指定任何訪問(wèn)修飾符,否則 編譯器會(huì)報(bào)錯(cuò)。
  • 7. 接口成員不能有static、abstract、override、virtual修飾符,使用new修飾符不會(huì)報(bào)錯(cuò),但會(huì)給出警告說(shuō)不需要關(guān)鍵字new。
  • 8. 在聲明接口成員的時(shí)候,不準(zhǔn)為接口成員編寫(xiě)具體的可執(zhí)行代碼,也就是說(shuō),只要在對(duì)接口進(jìn)行聲明時(shí)指明接口的成員名稱(chēng)和參數(shù)就可以了。
  • 9. 接口一旦被實(shí)現(xiàn),實(shí)現(xiàn)類(lèi)必須實(shí)現(xiàn)接口中的所有成員,除非實(shí)現(xiàn)類(lèi)本身是抽象類(lèi)(通過(guò)具體的可執(zhí)行代碼實(shí)現(xiàn)接口抽象成員的操作)。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

很多時(shí)候看到這么多的概念,也是云里霧里的。項(xiàng)目中的接口使用也是按照老代碼依葫蘆畫(huà)瓢。如果是自己練手的代碼或者demo,也是沒(méi)有使用接口。(給自己的借口就是,我只是做些小的東西,根本就不需要使用接口一樣可以跑很溜啊。)

?

接口是什么?(說(shuō)說(shuō)我自己的理解,不一定對(duì))

接口就是為了更換一個(gè)可能過(guò)時(shí)或者錯(cuò)誤的實(shí)現(xiàn)而準(zhǔn)備的。就想我們的電腦,里面就到處都是接口。usb、內(nèi)存條、硬盤(pán)、電池、鍵盤(pán)...等等都是有各自的接口。我們可以通過(guò)硬盤(pán)接口換個(gè)更大的硬盤(pán)或者換個(gè)更快的固態(tài)硬盤(pán)。如果鍵盤(pán)壞了,也可以通過(guò)鍵盤(pán)接口買(mǎi)個(gè)新的鍵盤(pán)換上去。這就是接口明顯的好處。接口也可以理解成大家的約定。約定了特定接口的大小功能等等。

?

那么我們寫(xiě)代碼也是一樣,在某些地方可能會(huì)經(jīng)常變動(dòng),邏輯會(huì)經(jīng)常修改的地方使用接口約定。下面我們就用硬盤(pán)的接口來(lái)做示例吧。

首先定義一個(gè)硬盤(pán)接口。(一個(gè)name屬性,一個(gè)讀一個(gè)寫(xiě)的方法

/// <summary> /// 硬盤(pán)接口 /// </summary> interface IHardDisk {/// <summary>/// 硬盤(pán)的名字屬性/// </summary>string name { get; }/// <summary>/// 讀取數(shù)據(jù)方法/// </summary>void read();/// <summary>/// 寫(xiě)數(shù)據(jù)/// </summary>void write(string str); }

然后我們買(mǎi)了一個(gè)200G的硬盤(pán),它實(shí)現(xiàn)了上面的接口。

public class HardDisk200 : IHardDisk {public string name{get{return "我是200G硬盤(pán)";}}public void read(){Console.WriteLine("我可以寫(xiě)入數(shù)據(jù)哦....");}public void write(string str){Console.WriteLine(str);}}

在電腦中使用這個(gè)硬盤(pán)。

static void Main(string[] args) {//這里的h就是一個(gè)插在接口上的設(shè)備IHardDisk h = new HardDisk200();h.read();h.write(h.name + ",我可以寫(xiě)入數(shù)據(jù)哦");Console.ReadKey(); }

?

某天,我們發(fā)現(xiàn)這個(gè)硬盤(pán)太小了,需要換個(gè)1T的。(那樣我們可以存很多很多的電影>_<),那么買(mǎi)吧。

public class HardDisk1T : IHardDisk {public string name{get{return "我是1T硬盤(pán)";}} public void read(){Console.WriteLine("我可以寫(xiě)入數(shù)據(jù)哦....");} public void write(string str){Console.WriteLine(str);} }

然后怎么使用了?只要在電腦上的接口直接插上新的硬盤(pán)就ok了,其他的什么地方都不用改。

?

這就是使用接口的好處。當(dāng)某天我們發(fā)現(xiàn)電腦太慢了,我們可以買(mǎi)個(gè)固態(tài)硬盤(pán),直接在接口使用的地方換上就可以了,其他地方完全不用修改。

這樣,我們就可以在不同時(shí)期或不同情況下靈活更換繼承實(shí)現(xiàn)了接口的任何對(duì)象,而不用修改其它地方的代碼。

又或者說(shuō),實(shí)現(xiàn)了這個(gè)接口的設(shè)備就是存儲(chǔ)設(shè)備。(它一定有存也一定可以?xún)?chǔ),也就是一定可以寫(xiě)入和讀出數(shù)據(jù)。

?

依賴(lài)注入

在我們了解了什么是接口之后,我們接著來(lái)說(shuō)說(shuō)今天主要的主題吧。

還是先從例子入手,且是我們學(xué)過(guò)編程都知道的例子,三層。(什么?你不知道什么是三層?那你別看了,先補(bǔ)習(xí)了再過(guò)來(lái)

我們先來(lái)寫(xiě)個(gè)簡(jiǎn)單的三層偽代碼。

DAL:

public class DALMsSqlHelper{public int add(string str){//...省略具體實(shí)現(xiàn)return 1;}//...省略具體實(shí)現(xiàn),如修改 刪除 查詢(xún)}

BLL:

public class BLLAddStudent {DALMsSqlHelper mssql = null;public BLLAddStudent(){mssql = new DALMsSqlHelper();}public int addStudent(){string str = ""; //...省略具體實(shí)現(xiàn)return mssql.add(str);} }

UI:

public class UI{BLLAddStudent s = new BLLAddStudent();public UI(){s.addStudent();}}

應(yīng)該說(shuō)簡(jiǎn)單得不能在簡(jiǎn)單的三層。

就在系統(tǒng)用了一年之后,老板說(shuō):”聽(tīng)說(shuō)oracle很牛逼,大公司都是用的oracle。咱們也換上吧。“。 好,那就換吧。

DAL:

public class DALOracleSqlHelper {public int addOracle(string str){//...省略具體實(shí)現(xiàn)return 1;}//...省略具體實(shí)現(xiàn),如修改 刪除 查詢(xún) }

顯然BLL也要進(jìn)行修改,因?yàn)锽LL引用了DAL的查詢(xún)類(lèi)。

BLL:

public class BLLAddStudent {DALOracleSqlHelper mssql = null;public BLLAddStudent(){mssql = new DALOracleSqlHelper();}public int addStudent(){string str = ""; //...省略具體實(shí)現(xiàn)return mssql.addOracle(str);} }

不就換個(gè)數(shù)據(jù)庫(kù)嗎?為何修改這么大,要是老板哪天又要換回oracle怎么辦?這得好好想個(gè)辦法。

首先,我們定義一個(gè)數(shù)據(jù)訪問(wèn)的接口。

public interface ISqlHelper {int add(); //...省略具體實(shí)現(xiàn),如修改 刪除 查詢(xún) }

DAL修改如下:

public class DALMsSqlHelper : ISqlHelper {public int add(string str){//...省略具體實(shí)現(xiàn)return 1;}//...省略具體實(shí)現(xiàn),如修改 刪除 查詢(xún) }public class DALOracleSqlHelper : ISqlHelper {public int addOracle(string str){//...省略具體實(shí)現(xiàn)return 1;}//...省略具體實(shí)現(xiàn),如修改 刪除 查詢(xún)public int add(string str){//...省略具體實(shí)現(xiàn)return 1;} }

BLL:

public class BLLAddStudent{ISqlHelper mssql = null;public BLLAddStudent(ISqlHelper sqlhelper){mssql = sqlhelper;}public int addStudent(){string str = ""; //...省略具體實(shí)現(xiàn)return mssql.add(str);}}

UI:

public class UI { public UI(){ISqlHelper sqlhelper = new DALOracleSqlHelper();BLLAddStudent s = new BLLAddStudent(sqlhelper);s.addStudent();} }

如果哪天老板又要換會(huì)mssql怎樣辦。那么僅僅只要修改UI

?

又過(guò)一年之后,因?yàn)楣静痪皻狻K杂謥?lái)需求了。老板:”唉,算了。我們還是用mysql吧。免費(fèi)的,為公司節(jié)省點(diǎn)“。那么我們又要修改了。

首先需要重新寫(xiě)個(gè)mysql的實(shí)現(xiàn)。

DAL:

public class DALMySqlHelper : ISqlHelper {public int add(string str){//...省略具體實(shí)現(xiàn)return 1;}//...省略具體實(shí)現(xiàn),如修改 刪除 查詢(xún) }

UI實(shí)現(xiàn)如下:

public class UI { public UI(){ISqlHelper sqlhelper = new DALMySqlHelper();BLLAddStudent s = new BLLAddStudent(sqlhelper);s.addStudent();} }

我們有沒(méi)有發(fā)現(xiàn)。我們只是在DAL新增了一個(gè)mysql的實(shí)現(xiàn)和修改了下UI層的接口構(gòu)造。其中BLL我們根本就沒(méi)有動(dòng)它的。

是的,這樣我們就可以說(shuō)這里的UI對(duì)于BLL來(lái)說(shuō)就是”依賴(lài)注入“,BLL對(duì)于UI來(lái)說(shuō)就是”控制反轉(zhuǎn)“。所以,我覺(jué)得依賴(lài)注入和控制反轉(zhuǎn)是同一個(gè)概念,只是立場(chǎng)不同。

?

上面,我們看到了雖然BLL層已經(jīng)不需要變動(dòng)就可以新增一個(gè)數(shù)據(jù)源的訪問(wèn)。那么我們能不能也不修改UI層呢?

這里就可以用到我們上篇講的反射了。

?

然后,不管老板想怎么折騰,我只需要改改配置文件就可以了。甚至都不用動(dòng)代碼。(如果需要新增一個(gè)數(shù)據(jù)源操作,也只要重新實(shí)現(xiàn)下,然后改改配置文件)。

?

本文以同步至《C#基礎(chǔ)知識(shí)鞏固系列》

轉(zhuǎn)載于:https://www.cnblogs.com/zhaopei/p/5078539.html

總結(jié)

以上是生活随笔為你收集整理的三、依赖注入是什么?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。