ABP+AdminLTE+Bootstrap Table權限管理系統第四節--倉儲,服務,服務接口及依賴注入 ABP+AdminLTE+Bootstrap Table權限管理系統一期 ABP+Admi

返回總目錄:ABP+AdminLTE+Bootstrap Table權限管理系統一期html

AbpModule

     在ABP框架中,倉儲,服務,這塊算是最爲重要一塊之一了.ABP框架提供了建立和組裝模塊的基礎,一個模塊可以依賴於另外一個模塊,一個程序集可當作一個模塊,數據庫

一個模塊能夠經過一個類來定義這個模塊,而給定義這個類要繼承自已經瘋轉好的AbpModule..net經過反射來獲取這些程序集中的類或者方法設計模式

       模塊的調用每每涉及到前後順序,若是模塊A依賴於模塊B,那麼模塊B要在模塊A以前初始化,初始化就至關於註冊,如使用IocManager對登記類進行註冊,框架

      

    上面這個方法咱們就把MyModule1 注入到MyModule2中了,在調用MyModule2的時候能夠初始化MyModule1 .異步

     什麼是依賴注入呢?百科是這樣說:「依賴注入是一種軟件設計模式,一個或多個依賴項(或服務)被注入或經過引用傳遞到一個依賴對象,而且成爲客戶端狀態的一部分。這種模式把客戶端依賴項的建立從它本身的行爲中分離出來,容許程序設計成鬆耦合的,遵循依賴倒置和單一職責的原則。和服務定位器模式相比,它容許客戶端知道他們使用的系統查找依賴項。」函數

     不使用依賴注入技術,很難管理依賴項和發佈一個結構良好的應用。post

倉儲(repository)

 

     假設咱們有一個應用程序服務,使用倉儲(repository)類插入實體到數據庫。在這種狀況下,應用程序服務類依賴於倉儲(repository)類,以下單元測試

      

   UserService使用UserRepository插入Person到數據庫。可是這段代碼有一些問題:測試

1,服務層UserService經過接口IUserRepository調用CreatePerson實現新增一個User對象,看似調用了IUserRepository接口,可是實際上仍是依賴於倉促層的UserRepository.url

2,UserService經過IUserRepository建立對象的時候,實際上new一個UserRepository區實現,這與直接調用UserRepository無差異,IUserRepository失去存在的意義.

3,若是將來咱們須要修改UserRepository類,可是UserService依賴於它,這時候,咱們須要修改全部依賴UserRepository的類.

4,有了這樣的依賴,很難對UserService進行單元測試。

5,與"高內聚低耦合"的的原則背道而馳,這裏能夠看到服務層與倉儲層有依賴.

 爲了解決這些問題因而就有了下面這個版本.

        這就是工廠模式,實際上在abp以前我也常常用這種方式,很是繁瑣,搭框架總是出錯,UserRepositoryFactory是一個靜態類,建立並返回一個IUserRepository

UserService服務不須要直接去建立UserRepository.

        這種方法雖然能夠,可是依然存在一些問題.

1,UserService依然依賴於UserRepositoryFactory

2,每個倉儲都有寫一個工廠,很繁瑣.

3,測試性仍是很差.

依賴注入

 

解決辦法有幾種,包括屬性注入,構造函數注入,和依賴注入框架等等.

 

 

 上面就是abp中構造函數注入與屬性輸入的完美運用.如今,UserService不知道哪些類實現userRepository以及如何建立它。誰須要使用UserService,首先建立一個IUserServiceUserService並將其傳遞給構造函數就能夠了.

      有人可能說userRepository的從屬類裏面可能存在依賴,依賴注入框架自動化管理依賴關係都已經解決了這些問題.構造函數注入模式是一個完美的提供類的依賴關係的方式。經過這種方式,你不能建立類的實例,而不提供依賴項。它也是一個強大的方式顯式地聲明是什麼類的需求正確地工做。

       可是,在某些狀況下,該類依賴於另外一個類,但也能夠沒有它。這一般是適用於橫切關注點(如日誌記錄)。一個類能夠沒有工做日誌,但它能夠寫日誌若是你提供一個日誌對象。在這種狀況下,您能夠定義依賴爲公共屬性,而不是讓他們放在構造函數,上面例子中NullLogger.Instance 是一個單例對象,實現了ILogger接口,但實際上什麼都沒作(不寫日誌。它實現了ILogger實例,且方法體爲空),在咱們須要寫日誌的地方,咱們只須要UserService.Logger = new Log4NetLogger();如此,咱們就能夠寫入日誌了,若是不寫就不調用,所以是一個可選的依賴.

        幾乎全部的依賴注入框架都支持屬性注入模式

        ABP的依賴注入基於 Castle Windsor框架。Castle Windsor最成熟的DI框架之一。依賴注入的框架還有好多,如Unity,Ninject,StructureMap,Autofac等,以前我用過Unity其餘的幾個沒有研究過,依賴框架均可以自動解決依賴關係。他們能夠建立全部依賴項(遞歸地依賴和依賴關係)。因此你只須要根據注入模式寫類和類構造函數&屬性,其餘的交給DI框架處理!在良好的應用程序中,類甚至獨立於DI框架。整個應用程序只會有幾行代碼或類,顯示的與DI框架交互。

        有人說上面這個例子看不出來依賴注入啊,其實這裏UserService是繼承自IUserService,而IUserService繼承自IApplicationService,abp在IApplicationService封裝了不少東西,ABP會自動註冊它,由於它實現IApplicationService接口(它只是一個空的接口)。它會被註冊爲transient (每次使用都建立實例)。當你注入(使用構造函數注入)IUserService接口成一個類,UserService對象會被自動建立並傳遞給構造函數。

        命名約定在這裏很是重要。例如你能夠將名字PersonAppService改成 MyPersonAppService或另外一個包含「PersonAppService」後綴的名稱,因爲IPersonAppService包含這個後綴。可是你能夠不遵循PeopleService命名您的服務類。若是你這樣作,它將不會爲IPersonAppService自動註冊(它須要自注冊(self-registration)到DI框架,而不是接口),因此,若是你想要你應該手動註冊它.

 

    上一章咱們已經定義實體類,和DTOs,在倉儲中能夠直接調用,倉儲是在領域層和數據映射層的中介,使用相似集合的接口來存取領域對象.

      接口:

 實現:

 

   在例子中IRepository繼承自abp已經封裝好的IRepository<TEntity>中,在IRepository<TEntity>中已經爲咱們封裝好了許多方法,這就免得咱們在爲每個倉儲建立不一樣的方法了,這點很好以下圖.

 

    包含了各式各樣的方法,如增刪查改等方法.還有一些Async的異步方法.GetAll返回IQueryable<T>類型的對象。所以咱們能夠在調用完這個方法以後進行Linq操做.

如今項目中運用的是EF框架,因此若是ORM框架沒有提供Async的倉儲方法則它會以同步的方式操做。一樣地,舉例來講,InsertAsync操做起來和EF的新增是同樣的,由於EF會直到單元做業(unit of work)完成以後纔會寫入新實體到數據庫中(DbContext.SaveChanges)。

     數據庫鏈接的開啓和關閉,在倉儲方法中,ABP會自動化的進行鏈接管理.當倉儲方法被調用後,數據庫鏈接會自動開啓且啓動事務。當倉儲方法執行結束而且返回之後,全部的實體變化都會被儲存, 事務被提交而且數據庫鏈接被關閉,一切都由ABP自動化的控制。若是倉儲方法拋出任何類型的異常,事務會自動地回滾而且數據鏈接會被關閉。上述全部操做在實現了IRepository接口的倉儲類全部公開的方法中均可以被調用。若是倉儲方法調用其它倉儲方法(即使是不一樣倉儲的方法),它們共享同一個鏈接和事務。鏈接會由倉儲方法調用鏈最上層的那個倉儲方法所管理。

      另外全部的倉儲對象都是暫時性的。這就是說,它們是在有須要的時候纔會被建立。ABP大量的使用依賴注入,當倉儲類須要被注入的時候,新的類實體會由注入容器會自動地建立.

返回總目錄:ABP+AdminLTE+Bootstrap Table權限管理系統一期

相關文章
相關標籤/搜索