文檔目錄 本節內容: 簡介 一個快速示例 其它特性 啟動模板 如何使用 簡介 我們總是對不同的需求開發不同的應用。但至少在某些層面上,一次又一次地重覆實現通用的和類似的功能。如:授權,驗證,異常處理,日誌,本地化,資料庫連接管理,設置管理,審核日誌等功能。所以我們創建架構和最佳實踐,如分層和模塊架構 ...
本節內容:
我們總是對不同的需求開發不同的應用。但至少在某些層面上,一次又一次地重覆實現通用的和類似的功能。如:授權,驗證,異常處理,日誌,本地化,資料庫連接管理,設置管理,審核日誌等功能。所以我們創建架構和最佳實踐,如分層和模塊架構,DDD,依賴註入等,並嘗試開發應用時基於一些約定。
由於所有這些是非常耗時而且很難單獨創建並可適用於每個項目,許多公司創建自己的框架,他們用自己的框架能快速開發新應用而且不出錯。但不是所有的公司都是幸運的,大部分公司沒有時間,預算和團隊來開發好的框架。他們甚至都沒有可能創建一個框架,因為編寫文檔,培訓開發人員和維護框架都是非常困難的。
ASP.NET Boilerplate (ABP) 是一個開源並且有豐富文檔的應用框架,開發宗旨是:“為所有公司,所有開發人員,開發出一個通用框架!”,而且不只是一個框架,同時提供一個強大的基於DDD的構架模型和最佳實踐。
讓我們從一個簡單的類來體會一下ABP帶來的便利:
public class TaskAppService:ApplicationService,ITaskAppService { private readonly IRepository<Task> _taskRepository; public TaskAppService(IRepository<Task> taskRepository) { _taskRepository = taskRepository; } [AbpAuthorize(MyPermissions.UpdatingTasks)] public async Task UpdateTask(UpdateTaskInput input) { Logger.Info("Updating a task for input: " + input); var task = await _taskRepository.FirstOrDefaultAsync(input.TaskId); if (task == null) { throw new UserFriendlyException(L("CouldNotFoundTheTaskMessage")); } Input.MapTo(task); } }
示例里我們看到一個應用服務方法,在DDD中,應用服務方法是在表示層執行應用的用戶用例的。我們可以想成UpdateTask方法是被Ajax調用。讓我們看看ABP帶來的便利:
- 依賴註入:ABP使用並提供一個強大而且符合約定的DI框架。上述的應用服務,按照約定臨時的(每個請求Request創建一個)註冊到DI容器,它能簡單地註入所有依賴項(如示例中的Irepository<Task>)。
- 倉儲:ABP能為每個實體創建一個預設的倉儲(如示例中的Irepository<Task>)。預設倉儲包含許多有用的方法,如示例中的FirstOrDefault方法。我們可以根據需要,很容易地擴展預設倉儲。倉儲抽象了DBMS和ORM以及簡化了數據訪問邏輯。
- 授權:ABP可以檢查許可。如果當前用戶沒有“updating task”許可權或是未登錄,ABP就會阻止他們訪問UpdateTask方法。用陳述性的特性來簡化授權,當然還有另外的授權方式。
- 驗證:ABP自動檢查input是否為null。根據標準的數據註釋特性和自定義驗證規則,檢查一個input的所有屬性。如果請求沒有通過驗證,會拋出一個對應的驗證異常。
- 審核日誌:根據約定和配置,每個請求的用戶、瀏覽器、Ip地址、調用服務、方法、參數、調用時間、執行耗時和其它的一些信息會被自動地保存下來。
- 工作單元:在ABP里,每個應用服務方法都預設地被認定為一個工作單元。在方法開始前,它自動創建一個連接並開啟一個事務。如果方法成功完成,接著事務會被提交並釋放連接。即使是使用不同的倉儲或是方法,它們都可以是原子性(事務性)的,並且當事務提交時實體中所有的修改都自動地被保存。因此,如同示例所示,我們甚至不需要去調用_repository.Update(task)方法。
- 異常處理:我們幾乎不用在一個使用ABP的Web應用中寫異常處理。所有的異常都自動地被預設處理。當一個異常發生,ABP自動記錄它並返回一個對應的結果給客戶端。例如,一個AJAX請求,它會返回一個Json對象給客戶端,告知發生了一個錯誤。如示例所示,UserFriendlyException可以向客戶端隱藏具體的異常,顯示友好信息。它同樣可以在客戶端理解並處理客戶端錯誤,並向用戶顯示對應的信息。
- 日誌:如你所見,我們可以用定義在基類中的Logger對象寫日誌。預設使用Log4Net,不過這是可修改和可配置的。
- 本地化:請註意我們在拋出異常時,使用了L方法。因此,它可自動依據用戶區域,使用相應的本地化信息。當然,我們需要在某處定義CouldNotFoundTheTaskMessage(更多信息參見“本地化”文檔)。
- 自動映射:最後一行代碼,我們使用ABP的MapTo擴展方法來映射input屬性到實體屬性。它使用AutoMapper庫來執行映射。因此,我們可以簡單地基於命名約定,從一個對象映射到另一個。
- 動態Web API 層:實際上TaskAppService是一個簡單的類(甚至是不需要從ApplicationService繼承)。我們通常包裝一個Web API 控制器為Javascript客戶端公開方法,ABP會在運行時自動地完成這件事。因此,我們可以直接在客戶端使用應用服務。
- 動態Javascript AJAX 代理:ABP創建Javascript代理方法,以便就本地調用一樣,來調用應用服務。
通過這麼一個簡單類我們能看到ABP的便利。完成這些任務一般來說都是很費時的,但是所有的一切,ABP都自動處理了。
除了示例所示,ABP提供了一個強大的基礎架構和應用模型,下列為ABP的其它特性:
- 模塊化:提供一個強大的基礎架構來創建可重用的模塊。
- 數據過濾:提供自動地數據過濾來實現一些模式,像軟刪除和多租戶。
- 多租戶:完全地支持多租戶,包含單資料庫或每租戶一個單獨資料庫。
- 設置管理:提供一個基礎架構來讀取/修改應用、租戶和用戶級別的設置。
- 單元和集成測試:以可測試為宗旨,當然提供基礎類來簡化單元測試和集成測試。點擊查看更多相關信息。
開始一個新的解決方案、創建層、安裝nuget包、創建一個簡單的佈局和菜單...所有這些都是耗時的工作。
ABP提供預創建的啟動模板,使開始一個新的解決方案更簡單。模板支持SPA(單頁面應用)和MPA(多頁面MVC應用)結構。同時允許我們使用不同的ORM工具。
ABP開源項目在Github上,分發在Nuget上。“啟動模板”是使用ABP的最簡單方式(按文檔所述操作)。