ABP理論學習之開篇介紹


返回總目錄


為了和2016年春節賽跑,完成該系列博客,我犧牲了今天中午的時間來完成該系列的第一篇————開篇介紹。開篇介紹嘛,讀過大學教材的同學都知道,這玩意總是那么無聊,跟考試沒關系,干脆直接跳過,呵呵,多么美好的大學時光啊!不過,現在想想,開篇介紹確實不怎么重要,它只是告訴我們今后我要開始講什么了,主要講什么,大概瀏覽下重點。
哦了,不扯了,時間不多了,干活!


本篇目錄

介紹###

我們總是基於不同的需求創建不同的應用,但是在一定程度上,總在反復地實現通用而相似的結構。這些通用的結構包括授權,驗證,異常處理,日志,本地化,數據庫連接管理,設置管理,審計日志等。而且,我們總是在構建體系結構和最佳實踐,比如分層模塊化架構,領域驅動設計(DDD),依賴注入等等。同時也在嘗試基於慣例開發應用。

因為這些都是非常耗時的,並且對於每個項目單獨創建是很困難的,所以很多公司都會創建自己私有的框架。通過使用私有的框架,他們總是可以快速地開發新的應用,同時應用的bug又會更少。當然了,不是所有的公司都是那么幸運了,你以為中國所有的公司都是BAT啊?!大多數公司還是沒有時間,預算和團隊來開發他們自己的私人框架。即使他們有可能構建這么一個框架,寫文檔,培訓開發者以及維護也是很難的。

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中,表現層直接使用應用服務來執行該應用的用例(其實就是一些操作方法)。我們還可以考慮使用Ajax調用上面的UpdateTask方法。

下面讓我們總結一下ABP的一些優點:

  • 依賴注入:ABP使用並提供了一個健壯而又傳統的DI基礎設施。因為上面的類是在一個應用服務中定義的,所以它會按照慣例約定短暫地(每個請求創建一次)注冊到DI容器中。它也簡單地注入了所有依賴(本例中注入了IRepository )。
  • 倉儲:ABP可以為每一個實體創建一個默認的倉儲(本例中是IRepository )。默認的倉儲有許多有用的方法,如本例中的 FirstOrDefault。我們也可以根據我們的需求輕易地擴展默認倉儲。倉儲抽象了DBMS和ORM,並簡化了數據的訪問邏輯。
  • 授權:ABP可以檢測權限。如果當前的用戶沒有“updating task”的權限或者沒登錄,那么ta不能訪問UpdateTask方法。它使用聲明式的特性簡化了授權,而且還有其他的授權方法。
  • 驗證:ABP會自動檢測輸入是否為null。它也基於標准的數據注解特性和自定義的驗證規則驗證輸入對象的所有屬性。如果請求不合法,那么它會拋出一個合適的驗證異常。
  • 審計日志:用戶,瀏覽器,IP地址,調用服務,方法,參數,調用時間,執行時長和其他的一些信息也會基於慣例和配置為每個請求自動地保存。
  • 工作單元(Unit of Work):在ABP中,每個應用服務方法默認視為一個工作單元。它會自動創建一個連接並在方法的開始位置開啟一個事務。如果方法不報異常地成功完成了,那么事務會提交並且連接被釋放。即使該方法使用了不同的倉儲或者方法,它們全部也都是原子的(事務的)。當事務提交時,實體的所有改變都會自動保存。因此,正如這里展示的那樣,我們甚至都不用調用_repository.Update(task)方法。
  • 異常處理:在一個使用了ABP框架的Web應用中,我們基本上不用處理異常。所有的異常都會默認自動處理。如果一個異常發生了,那么ABP會自動地記錄它,然后返回給客戶端一個合適的結果。比如,如果這是一個Ajax請求,那么它會返回一個JSON到客戶端,指明發生了一個錯誤。本例中使用了一個UserFriendlyException,這樣就隱藏了客戶端實際的異常信息。它也理解並處理客戶端的錯誤,最后將合適的信息呈現給用戶。
  • 日志:我們可以使用在基類中定義的Logger來寫日志。ABP默認使用了Log4Net,但是它是可改變的或可配置的。
  • 本地化(Localization):注意當拋出異常的時候我們使用了L方法。因此,它會基於當前用戶的文化自動進行本地化。當然,我們可以在某些地方定義CouldNotFoundTheTaskMessage
  • 自動映射:上面的最后一行代碼,我們使用了ABP的MapTo擴展方法將輸入對象的屬性映射到實體屬性。它使用了AutoMapper庫來執行映射。因此,我們可以基於命名慣例輕易地將屬性從一個對象上映射到另一個對象上。我的AutoMapper系列學習博客:**http://www.cnblogs.com/farb/p/AutoMapperContent.html **。
  • 動態Web API層:實際上,TaskAppService 是一個簡單的類(甚至不需要從ApplicationService 繼承)。我們一般會寫一個Web API Controller包裝器來將方法暴露給javascript客戶端。ABP在運行時會自動完成。這樣,我們可以從客戶端直接使用應用服務方法。
  • 動態Ajax代理:ABP創建了javascript代理方法,它們可以調用應用服務方法就像調用客戶端的javascript方法一樣簡單。

在這么一個簡單的類中,我們看到了ABP的優勢。所有的這些任務正常情況下都是要花費很多時間的,但是所有的這些ABP自動幫我們完成了。

其他###

除了這個簡單的例子,ABP也提供了一個健壯的基礎設施和應用模型。下面是ABP的一下其他特征:

  • 模塊化:提供了一個健壯的基礎設施來生成可復用的模塊。
  • 數據過濾器:提供了自動的數據過濾來實現一些模式,比如軟刪除和多租戶。
  • 多租戶:支持單數據庫、多客戶形式的多租戶。
  • 設置管理:提供了健壯的基礎設施類獲得或者更改應用,租戶和用戶級別的設置。
  • 單元測試和集成測試:基於可測試性構建,也提供了一些基類來簡化單元測試和集成測試。

更多的特征,請認真閱讀其他文檔。

啟動模板###

開始一個新的解決方案,創建層,安裝nuget包,創建一個簡單的布局和菜單...所有的這些都是非常耗時的。

ABP提供了一個預生成的啟動模板,有了它,創建一個新的解決方案更容易了。模板支持SPA(單頁應用)MPA(多頁應用)。而且,我們可以選擇不同的ORM。

如何使用###

ABP的源碼已經推送到了Github上,Nuget包也已經發布到了Nuget上。開始使用ABP最簡單的方式就是使用ABP官網的模板創建項目,然后跟着文檔來學習。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM