ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)第四節(jié)--倉(cāng)儲(chǔ),服務(wù),服務(wù)接口及依賴注入

ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期
Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS
前往博客園總目錄:ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期

在ABP框架中,倉(cāng)儲(chǔ),服務(wù),這塊算是最為重要一塊之一了.ABP框架提供了創(chuàng)建和組裝模塊的基礎(chǔ)囚霸,一個(gè)模塊能夠依賴于另一個(gè)模塊,一個(gè)程序集可看成一個(gè)模塊,
一個(gè)模塊可以通過一個(gè)類來定義這個(gè)模塊腰根,而給定義這個(gè)類要繼承自已經(jīng)瘋轉(zhuǎn)好的AbpModule..net通過反射來獲取這些程序集中的類或者方法
模塊的調(diào)用往往涉及到先后順序,如果模塊A依賴于模塊B,那么模塊B要在模塊A之前初始化,初始化就相當(dāng)于注冊(cè),如使用IocManager對(duì)登記類進(jìn)行注冊(cè),


上面這個(gè)方法我們就把MyModule1 注入到MyModule2中了,在調(diào)用MyModule2的時(shí)候可以初始化MyModule1 .
什么是依賴注入呢?百科是這樣說:“依賴注入是一種軟件設(shè)計(jì)模式,一個(gè)或多個(gè)依賴項(xiàng)(或服務(wù))被注入或通過引用傳遞到一個(gè)依賴對(duì)象拓型,并且成為客戶端狀態(tài)的一部分。這種模式把客戶端依賴項(xiàng)的創(chuàng)建從它自己的行為中分離出來,允許程序設(shè)計(jì)成松耦合的靠闭,遵循依賴倒置和單一職責(zé)的原則点弯。和服務(wù)定位器模式相比捡絮,它允許客戶端知道他們使用的系統(tǒng)查找依賴項(xiàng)。”
不使用依賴注入技術(shù),很難管理依賴項(xiàng)和發(fā)布一個(gè)結(jié)構(gòu)良好的應(yīng)用。
假設(shè)我們有一個(gè)應(yīng)用程序服務(wù),使用倉(cāng)儲(chǔ)(repository)類插入實(shí)體到數(shù)據(jù)庫(kù)。在這種情況下,應(yīng)用程序服務(wù)類依賴于倉(cāng)儲(chǔ)(repository)類,如下

UserService使用UserRepository插入Person到數(shù)據(jù)庫(kù)阅羹。但是這段代碼有一些問題:

  1. 服務(wù)層UserService通過接口IUserRepository調(diào)用CreatePerson實(shí)現(xiàn)新增一個(gè)User對(duì)象,看似調(diào)用了IUserRepository接口,但是實(shí)際上還是依賴于倉(cāng)促層的UserRepository.
  2. UserService通過IUserRepository創(chuàng)建對(duì)象的時(shí)候,實(shí)際上new一個(gè)UserRepository區(qū)實(shí)現(xiàn),這與直接調(diào)用UserRepository無(wú)差別,IUserRepository失去存在的意義.
  3. 如果未來我們需要修改UserRepository類,但是UserService依賴于它,這時(shí)候,我們需要修改所有依賴UserRepository的類.
  4. 有了這樣的依賴,很難對(duì)UserService進(jìn)行單元測(cè)試看尼。
  5. 與"高內(nèi)聚低耦合"的的原則背道而馳,這里可以看到服務(wù)層與倉(cāng)儲(chǔ)層有依賴.
    為了解決這些問題于是就有了下面這個(gè)版本.

    這就是工廠模式,實(shí)際上在abp之前我也經(jīng)常用這種方式,非常繁瑣,搭框架老是出錯(cuò),UserRepositoryFactory是一個(gè)靜態(tài)類,創(chuàng)建并返回一個(gè)IUserRepository

UserService服務(wù)不需要直接去創(chuàng)建UserRepository.
這種方法雖然可以,但是依然存在一些問題.

  1. UserService依然依賴于UserRepositoryFactory
  2. 每一個(gè)倉(cāng)儲(chǔ)都有寫一個(gè)工廠,很繁瑣.
  3. 測(cè)試性還是不好.
    解決辦法有幾種,包括屬性注入,構(gòu)造函數(shù)注入,和依賴注入框架等等.


上面就是abp中構(gòu)造函數(shù)注入與屬性輸入的完美運(yùn)用.現(xiàn)在,UserService不知道哪些類實(shí)現(xiàn)userRepository以及如何創(chuàng)建它描孟。誰(shuí)需要使用UserService廉羔,首先創(chuàng)建一個(gè)IUserServiceUserService并將其傳遞給構(gòu)造函數(shù)就可以了.
有人可能說userRepository的從屬類里面可能存在依賴,依賴注入框架自動(dòng)化管理依賴關(guān)系都已經(jīng)解決了這些問題.構(gòu)造函數(shù)注入模式是一個(gè)完美的提供類的依賴關(guān)系的方式竹挡。通過這種方式好啰,你不能創(chuàng)建類的實(shí)例搅窿,而不提供依賴項(xiàng)。它也是一個(gè)強(qiáng)大的方式顯式地聲明是什么類的需求正確地工作借卧。
但是镰吵,在某些情況下勺馆,該類依賴于另一個(gè)類,但也可以沒有它紧卒。這通常是適用于橫切關(guān)注點(diǎn)(如日志記錄)盆佣。一個(gè)類可以沒有工作日志颤诀,但它可以寫日志如果你提供一個(gè)日志對(duì)象崖叫。在這種情況下养叛,您可以定義依賴為公共屬性,而不是讓他們放在構(gòu)造函數(shù),上面例子中NullLogger.Instance 是一個(gè)單例對(duì)象掉缺,實(shí)現(xiàn)了ILogger接口丑瞧,但實(shí)際上什么都沒做(不寫日志获雕。它實(shí)現(xiàn)了ILogger實(shí)例仓蛆,且方法體為空),在我們需要寫日志的地方,我們只需要UserService.Logger = new Log4NetLogger();如此,我們就可以寫入日志了,如果不寫就不調(diào)用,因此是一個(gè)可選的依賴.
幾乎所有的依賴注入框架都支持屬性注入模式
ABP的依賴注入基于 Castle Windsor框架睁冬。Castle Windsor最成熟的DI框架之一。依賴注入的框架還有好多看疙,如Unity豆拨,Ninject,StructureMap能庆,Autofac等,之前我用過Unity其他的幾個(gè)沒有研究過,依賴框架都可以自動(dòng)解決依賴關(guān)系施禾。他們可以創(chuàng)建所有依賴項(xiàng)(遞歸地依賴和依賴關(guān)系)。所以你只需要根據(jù)注入模式寫類和類構(gòu)造函數(shù)&屬性搁胆,其他的交給DI框架處理弥搞!在良好的應(yīng)用程序中邮绿,類甚至獨(dú)立于DI框架。整個(gè)應(yīng)用程序只會(huì)有幾行代碼或類攀例,顯示的與DI框架交互船逮。
有人說上面這個(gè)例子看不出來依賴注入啊,其實(shí)這里UserService是繼承自IUserService,而IUserService繼承自IApplicationService,abp在IApplicationService封裝了很多東西,ABP會(huì)自動(dòng)注冊(cè)它,因?yàn)樗鼘?shí)現(xiàn)IApplicationService接口(它只是一個(gè)空的接口)粤铭。它會(huì)被注冊(cè)為transient (每次使用都創(chuàng)建實(shí)例)挖胃。當(dāng)你注入(使用構(gòu)造函數(shù)注入)IUserService接口成一個(gè)類,UserService對(duì)象會(huì)被自動(dòng)創(chuàng)建并傳遞給構(gòu)造函數(shù)梆惯。
命名約定在這里非常重要酱鸭。例如你可以將名字PersonAppService改為 MyPersonAppService或另一個(gè)包含“PersonAppService”后綴的名稱,由于IPersonAppService包含這個(gè)后綴加袋。但是你可以不遵循PeopleService命名您的服務(wù)類凛辣。如果你這樣做,它將不會(huì)為IPersonAppService自動(dòng)注冊(cè)(它需要自注冊(cè)(self-registration)到DI框架职烧,而不是接口)扁誓,所以,如果你想要你應(yīng)該手動(dòng)注冊(cè)它.

倉(cāng)儲(chǔ)

上一章我們已經(jīng)定義實(shí)體類,和DTOs,在倉(cāng)儲(chǔ)中可以直接調(diào)用,倉(cāng)儲(chǔ)是在領(lǐng)域?qū)雍蛿?shù)據(jù)映射層的中介,使用類似集合的接口來存取領(lǐng)域?qū)ο?

接口:

實(shí)現(xiàn):

在例子中IRepository繼承自abp已經(jīng)封裝好的IRepository<TEntity>中,在IRepository<TEntity>中已經(jīng)為我們封裝好了許多方法,這就省得我們?cè)跒槊恳粋€(gè)倉(cāng)儲(chǔ)創(chuàng)建不同的方法了,這點(diǎn)很好如下圖.


包含了各式各樣的方法,如增刪查改等方法.還有一些Async的異步方法.GetAll返回IQueryable<T>類型的對(duì)象蚀之。因此我們可以在調(diào)用完這個(gè)方法之后進(jìn)行Linq操作.
現(xiàn)在項(xiàng)目中運(yùn)用的是EF框架,所以如果ORM框架沒有提供Async的倉(cāng)儲(chǔ)方法則它會(huì)以同步的方式操作蝗敢。同樣地,舉例來說,InsertAsync操作起來和EF的新增是一樣的,因?yàn)镋F會(huì)直到單元作業(yè)(unit of work)完成之后才會(huì)寫入新實(shí)體到數(shù)據(jù)庫(kù)中(DbContext.SaveChanges)。
數(shù)據(jù)庫(kù)連接的開啟和關(guān)閉足删,在倉(cāng)儲(chǔ)方法中,ABP會(huì)自動(dòng)化的進(jìn)行連接管理.當(dāng)倉(cāng)儲(chǔ)方法被調(diào)用后,數(shù)據(jù)庫(kù)連接會(huì)自動(dòng)開啟且啟動(dòng)事務(wù)寿谴。當(dāng)倉(cāng)儲(chǔ)方法執(zhí)行結(jié)束并且返回以后,所有的實(shí)體變化都會(huì)被儲(chǔ)存, 事務(wù)被提交并且數(shù)據(jù)庫(kù)連接被關(guān)閉,一切都由ABP自動(dòng)化的控制。如果倉(cāng)儲(chǔ)方法拋出任何類型的異常,事務(wù)會(huì)自動(dòng)地回滾并且數(shù)據(jù)連接會(huì)被關(guān)閉失受。上述所有操作在實(shí)現(xiàn)了IRepository接口的倉(cāng)儲(chǔ)類所有公開的方法中都可以被調(diào)用讶泰。如果倉(cāng)儲(chǔ)方法調(diào)用其它倉(cāng)儲(chǔ)方法(即便是不同倉(cāng)儲(chǔ)的方法),它們共享同一個(gè)連接和事務(wù)。連接會(huì)由倉(cāng)儲(chǔ)方法調(diào)用鏈最上層的那個(gè)倉(cāng)儲(chǔ)方法所管理拂到。
另外所有的倉(cāng)儲(chǔ)對(duì)象都是暫時(shí)性的痪署。這就是說,它們是在有需要的時(shí)候才會(huì)被創(chuàng)建。ABP大量的使用依賴注入兄旬,當(dāng)倉(cāng)儲(chǔ)類需要被注入的時(shí)候,新的類實(shí)體會(huì)由注入容器會(huì)自動(dòng)地創(chuàng)建.

返回簡(jiǎn)書總目錄:ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期
前往博客園總目錄:ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末狼犯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子领铐,更是在濱河造成了極大的恐慌悯森,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,423評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绪撵,死亡現(xiàn)場(chǎng)離奇詭異瓢姻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)音诈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門幻碱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來续膳,“玉大人,你說我怎么就攤上這事收班。” “怎么了谒兄?”我有些...
    開封第一講書人閱讀 157,019評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵摔桦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我承疲,道長(zhǎng)邻耕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,443評(píng)論 1 283
  • 正文 為了忘掉前任燕鸽,我火速辦了婚禮兄世,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘啊研。我一直安慰自己御滩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,535評(píng)論 6 385
  • 文/花漫 我一把揭開白布党远。 她就那樣靜靜地躺著削解,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沟娱。 梳的紋絲不亂的頭發(fā)上氛驮,一...
    開封第一講書人閱讀 49,798評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音济似,去河邊找鬼矫废。 笑死,一個(gè)胖子當(dāng)著我的面吹牛砰蠢,可吹牛的內(nèi)容都是我干的蓖扑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,941評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼娩脾,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼赵誓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起柿赊,我...
    開封第一講書人閱讀 37,704評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤俩功,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后碰声,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诡蜓,經(jīng)...
    沈念sama閱讀 44,152評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,494評(píng)論 2 327
  • 正文 我和宋清朗相戀三年胰挑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蔓罚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椿肩。...
    茶點(diǎn)故事閱讀 38,629評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖豺谈,靈堂內(nèi)的尸體忽然破棺而出郑象,到底是詐尸還是另有隱情,我是刑警寧澤茬末,帶...
    沈念sama閱讀 34,295評(píng)論 4 329
  • 正文 年R本政府宣布厂榛,位于F島的核電站,受9級(jí)特大地震影響丽惭,放射性物質(zhì)發(fā)生泄漏击奶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,901評(píng)論 3 313
  • 文/蒙蒙 一责掏、第九天 我趴在偏房一處隱蔽的房頂上張望柜砾。 院中可真熱鬧,春花似錦换衬、人聲如沸痰驱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)萄唇。三九已至,卻和暖如春术幔,著一層夾襖步出監(jiān)牢的瞬間另萤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,978評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工诅挑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留四敞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,333評(píng)論 2 360
  • 正文 我出身青樓拔妥,卻偏偏與公主長(zhǎng)得像忿危,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子没龙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,499評(píng)論 2 348