ABP(現代ASP.NET樣板開發框架)系列之15、ABP應用層——應用服務(Application services)
基於DDD的現代ASP.NET開發框架--ABP系列之15、ABP應用層——應用服務(Application services)
ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。
本文由東莞-天道提供翻譯
應用服務用於將領域(業務)邏輯暴露給展現層。展現層通過傳入DTO(資料傳輸物件)引數來呼叫應用服務,而應用服務通過領域物件來執行相應的業務邏輯並且將DTO返回給展現層。因此,展現層和領域層將被完全隔離開來。在一個理想的層級專案中,展現層應該從不直接訪問領域物件。
IApplicationService介面
在ABP中,一個應用服務需要實現IApplicationService介面。最好的實踐是針對每個應用服務都建立相應的介面。所以,我們首先定義一個應用服務介面,如下所示:
public interface IPersonAppService : IApplicationService { void CreatePerson(CreatePersonInput input); }
IPersonAppService只有一個方法,它將被展現層呼叫來建立一個新的Person。CreatePersonInput是一個DTO物件,如下所示:
public class CreatePersonInput : IInputDto { [Required] public string Name { get; set; }public string EmailAddress { get; set; } }
接著,我們實現IPersonAppService介面:
public class PersonAppService : IPersonAppService { private readonly IRepository<Person> _personRepository; public PersonAppService(IRepository<Person> personRepository) { _personRepository= personRepository; } public void CreatePerson(CreatePersonInput input) { var person = _personRepository.FirstOrDefault(p => p.EmailAddress == input.EmailAddress); if (person != null) { throw new UserFriendlyException("There is already a person with given email address"); } person = new Person { Name = input.Name, EmailAddress = input.EmailAddress }; _personRepository.Insert(person); } }
以下是幾個重要提示:
- PersonAppService通過IRepository來執行資料庫操作。它通過構造器注入模式來生成。我們在這裡使用了依賴注入。
- PersonAppService實現了IApplicationService(通過IPersonAppService繼承IApplicationService)。ABP會自動地把它註冊到依賴注入系統中,並可以注入到別的型別中使用。
- CreatePerson方法需要一個CreatePersonInput型別的引數。這是一個作為輸入的DTO,它將被ABP自動驗證其資料有效性。可以檢視DTO和資料有效性驗證(Validation)文件獲取相關細節。
應用服務型別
應用服務(Application Services)需要實現IApplicationService介面。當然,你可以選擇將你的應用服務(Application Services)繼承自ApplicationService基類,這樣你的應用服務也就自然而然的實現IApplicationService介面了。ApplicationService基類提供了方便的日誌記錄和本地化功能。在此建議你針對你的應用程式建立一個應用服務基類繼承自ApplicationService型別。這樣你就可以新增一些公共的功能來提供給你的所有應用服務使用。一個應用服務示例如下所示:
public class TaskAppService : ApplicationService, ITaskAppService { public TaskAppService() { LocalizationSourceName = "SimpleTaskSystem"; } public void CreateTask(CreateTaskInput input) { //記錄日誌,Logger定義在ApplicationService中 Logger.Info("Creating a new task with description: " + input.Description); //獲取本地化文字(L是LocalizationHelper.GetString(...)的簡便版本, 定義在 ApplicationService型別) var text = L("SampleLocalizableTextKey"); //TODO: Add new task to database... } }
本例中我們在建構函式中定義了LocalizationSourceName,但你可以在基類中定義它,這樣你就不需要在每個具體的應用服務中定義它。檢視日誌記錄(logging)和本地化(localization)文件可以獲取更多的相關資訊。
工作單元
在ABP中,一個應用服務方法預設是一個工作單元。
(1)連線 & 事務管理 (For connection & transaction management)
在應用服務方法中,如果我們需要呼叫兩個倉儲方法,那麼這些方法必須為一個事務。舉個例子:
public void CreatePerson(CreatePersonInput input) { var person = new Person { Name = input.Name, EmailAddress = input.EmailAddress }; _personRepository.Insert(person); _statisticsRepository.IncrementPeopleCount(); }
我們向Person表插入一個數據,接著在其他表中修改了Person計數字段的值。這兩個操作實現於不同的倉儲中,但是它們使用了相同的資料連線和事務。這是怎麼實現的呢?
對於UOW模式,當事務啟動並且開始執行CreatePerson方法的時候,ABP會自動地開啟資料庫。在方法結束時,如果未發生異常該事務將會被提交,並確保關閉資料庫連線。因此,CreatePerson方法中的所有資料庫操作將作為一個事務(具有原子性),當有異常丟擲時這些事務中的操作將會回滾。所以,示例中的兩個倉儲方法使用了相同的資料連線和事務。
當你呼叫倉儲中的GetAll()方法時,它將返回一個IQueryable。資料庫連線應會在呼叫倉儲方法後開啟。這是因為IQueryable和LINQ的延遲執行。當你呼叫類似ToList()方法時,資料庫查詢才會真正的開始執行。來看下面的示例:
public SearchPeopleOutput SearchPeople(SearchPeopleInput input) { //獲取 IQueryable<Person> var query = _personRepository.GetAll(); //過濾資料 if (!string.IsNullOrEmpty(input.SearchedName)) { query = query.Where(person => person.Name.StartsWith(input.SearchedName)); } if (input.IsActive.HasValue) { query = query.Where(person => person.IsActive == input.IsActive.Value); } //獲取分頁 var people = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList(); return new SearchPeopleOutput {People = Mapper.Map<List<PersonDto>>(people)}; }
由於一個應用服務(Application Services)方法就是一個工作單元,所以資料庫連線在方法執行期間都是開啟的。如果你在非應用服務(Application Services)中呼叫GetAll(),你需要顯式的使用工作單元模式。如:在Controller的Action方法中要使用GetAll()或呼叫多個有對資料庫操作的AppService方法時, 應該將Action方法使用virtual修飾,並在Action的上面通過[UnitOfWork]進行顯示開啟工作單元模式。
注意我使用了AutoMapper庫將List轉換成List。可以檢視DTO文件獲取相關細節。
譯者-天道注:這裡要說一下,就是uow和非uow模式的區別,兩種模式對於資料庫連線的開啟和關閉是不同的。對於控制器的方法,ABP預設是非 uow模式,此時如果呼叫方法會報錯,提示資料庫未連線。解決的辦法是在方法加上virtual。
(2)自動儲存資料修改 (For automatically saving changes)
對於工作單元方法(應用服務(Application Services)方法),在方法結束時ABP將會自動儲存所有資料修改。假設我們需要一個應用服務(Application Services)方法來更新一個Person的Name:
public void UpdateName(UpdateNameInput input) { var person = _personRepository.Get(input.PersonId); person.Name = input.NewName; }
就是這樣,Name被成功修改!我們甚至不需要呼叫_personRepository.Update方法。ORM框架在工作單元中會跟蹤所有實體修改並將修改更新到資料庫中。
應用服務的生命週期
所有應用服務(Application Services)例項的生命週期都是暫時的(Transient)。這意味著在每次使用都會建立新的應用服務(Application Services)例項。ABP堅決地使用依賴注入技術。當一個應用服務(Application Services)型別需要被注入時,該應用服務(Application Services)型別的新例項將會被依賴注入容器自動建立。檢視依賴注入(Dependency Injection)文件獲取更多資訊。
希望更多國內的架構師能關注到ABP這個專案,也許這其中有能幫助到您的地方,也許有您的參與,這個專案可以發展得更好。
歡迎加QQ群:
相關推薦
ABP(現代ASP.NET樣板開發框架)系列之15、ABP應用層——應用服務(Application services)
基於DDD的現代ASP.NET開發框架--ABP系列之15、ABP應用層——應用服務(Application services) ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 本文由東莞-天道提供翻譯 應用服務用於將領
ABP(現代ASP.NET樣板開發框架)系列之10、ABP領域層——實體
基於DDD的現代ASP.NET開發框架--ABP系列之10、ABP領域層——實體 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 本文由深圳-Carl提供翻譯 實體是DDD(領域驅動設計)的核心概念之一。Eric Eva
ABP(現代ASP.NET樣板開發框架)系列之4、ABP模組系統
基於DDD的現代ASP.NET開發框架--ABP系列之4、ABP模組系統 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 本文由東莞-天道提供翻譯 ABP模組系統簡介 ABP框架提供了建立和組裝模組的基礎,一個模組
ABP(現代ASP.NET樣板開發框架)系列之6、ABP依賴注入
基於DDD的現代ASP.NET開發框架--ABP系列之6、ABP依賴注入 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 本文由 上海-半冷 提供翻譯 什麼是依賴注入 如果你已經知道依賴注入的概念,建構函式和屬性注入
ABP(現代ASP.NET樣板開發框架)系列之9、ABP設定管理
基於DDD的現代ASP.NET開發框架--ABP系列之9、ABP設定管理 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 本文由山東-李偉提供翻譯 介紹 每個應用程式需要儲存一些設定並在應用程式的某個地方使用這些設定。
ABP(現代ASP.NET樣板開發框架)系列之2、ABP入門教程
基於DDD的現代ASP.NET開發框架--ABP系列之2、ABP入門教程 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 ASP.NET Boilerplate是一個用最佳實踐和流行技術開發現代WEB應用程式的新起點,它旨在成為一個通用的
ABP(現代ASP.NET樣板開發框架)系列之17、ABP應用層——引數有效性驗證
基於DDD的現代ASP.NET開發框架--ABP系列之17、ABP應用層——引數有效性驗證 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 應用程式的輸入資料首先應該被檢驗是否有效。輸入的資料能被使用者或其他應用程式提
ABP(現代ASP.NET樣板開發框架)系列之16、ABP應用層——資料傳輸物件(DTOs)
基於DDD的現代ASP.NET開發框架--ABP系列之16、ABP應用層——資料傳輸物件(DTOs) ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 資料傳輸物件(Data Transfer Objects)用於應用層
ABP(現代ASP.NET樣板開發框架)系列之13、ABP領域層——資料過濾器(Data filters)
基於DDD的現代ASP.NET開發框架--ABP系列之13、ABP領域層——資料過濾器(Data filters) ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 介紹 在資料庫開發中,我們一般會運用軟刪除(soft
ABP(現代ASP.NET樣板開發框架)系列之21、ABP展現層——Javascript函式庫
基於DDD的現代ASP.NET開發框架--ABP系列之21、ABP展現層——Javascript函式庫 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 ASP.NET Boilerplate的js庫提供了一些讓java
ABP(現代ASP.NET樣板開發框架)系列之14、ABP領域層——領域事件(Domain events)
基於DDD的現代ASP.NET開發框架--ABP系列之14、ABP領域層——領域事件(Domain events) ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 在C#中,一個類可以定義其專屬的事件並且其它類可以註冊該事
ABP(現代ASP.NET樣板開發框架)系列之5、ABP啟動配置
基於DDD的現代ASP.NET開發框架--ABP系列之5、ABP啟動配置 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 本文由 東莞-天道 提供翻譯 譯者注:在看這一節的內容之前,建議大家先下載module-ze
ABP(現代ASP.NET樣板開發框架)系列之3、ABP分層架構
基於DDD的現代ASP.NET開發框架--ABP系列之3、ABP分層架構 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 前言 為了減少複雜性和提高程式碼的可重用性,採用分層架構是一種被廣泛接受的技術。為了實現分層的
ABP(現代ASP.NET樣板開發框架)系列之19、ABP應用層——審計日誌
基於DDD的現代ASP.NET開發框架--ABP系列之19、ABP應用層——審計日誌 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 維基百科定義:審計跟蹤(也稱為稽核日誌)是一個安全相關的時間順序記錄,記錄這些記錄的
ABP(現代ASP.NET樣板開發框架)系列之23、ABP展現層——異常處理
基於DDD的現代ASP.NET開發框架--ABP系列之23、ABP展現層——異常處理 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 在 web 應用程式中,異常通常是在 MVC Controller actions
ABP(現代ASP.NET樣板開發框架)系列之8、ABP日誌管理
基於DDD的現代ASP.NET開發框架--ABP系列之8、ABP日誌管理 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 本文由東莞-天道提供翻譯 Server side(伺服器端) ASP.NET Boilerpla
ABP(現代ASP.NET樣板開發框架)系列之1、ABP總體介紹
基於DDD的現代ASP.NET開發框架--ABP系列之1、ABP總體介紹 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 ASP.NET Boilerplate是一個用最佳實踐和流行技術開發現代WEB應用程式的新起點,它旨在成為一個通用的
ABP(現代ASP.NET樣板開發框架)系列之12、ABP領域層——工作單元(Unit Of work)
基於DDD的現代ASP.NET開發框架--ABP系列之12、ABP領域層——工作單元(Unit Of work) ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 通用連線和事務管理方法 連線和事務管理是使用資料庫的應用程
ABP(現代ASP.NET樣板開發框架)系列之22、ABP展現層——導航欄設定
基於DDD的現代ASP.NET開發框架--ABP系列之22、ABP展現層——導航欄設定 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 每一個WEB應用程式都有導航選單,Abp也為使用者提供了通用的建立和顯示選單方式。
ABP(現代ASP.NET樣板開發框架)系列之7、ABP Session管理
基於DDD的現代ASP.NET開發框架--ABP系列之7、ABP Session管理 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 簡介 如果一個應用程式需要登入,則它必須知道當前使用者執行了什麼操作。因此ASP.