在ASP.NET Core中使用Apworks快速開發數據服務

很多關注我博客的朋友都知道我在2009年左右開發過一個名爲Apworks的企業級應用程序開發框架,旨在爲分佈式企業系統軟件開發提供面向領域驅動(DDD)的框架級別的解決方案,並對多種系統架構風格提供支持。這個框架的開發和維護我堅持了好久,一直到2015年,我都一直在不停地重構這個項目。目前這個項目在Github上也獲得了將近260的推薦數,不少對技術感興趣的朋友也一直與我保持着聯繫和交流,甚至還有愛好者自發組成了技術討論羣,專門討論分享Apworks框架。html

然而,隨着軟件開發技術和.NET的發展,這個框架的設計和研發技術都逐漸過期,重構難度逐漸加大,不少由其自己支持的技術,好比MSMQ、NHibernate也都逐漸淡出人們的視線,相比之下,雲計算、微服務、大數據、跨平臺等相關技術愈來愈多地引發了業界的關注,成功的案例也愈來愈多。如何基於雲平臺(PaaS + IaaS)快速搭建高效、經濟、穩定、安全的軟件系統架構,成爲了最近兩年的熱門話題。微軟也順應這樣的潮流,作出了不少的改變,就在短短的一到兩年時間,引領了.NET的跨平臺,開源了諸多著名的項目,好比.NET、Core CLR、Roslyn、ASP.NET、Entity Framework、Powershell等等,而且開始接受並擁抱非Windows的操做系統,好比Visual Studio跨平臺、Powershell跨平臺、SQL Server跨平臺、Visual C++支持多種編譯器等等。很明顯,原有的Apworks已經再也不具有跨平臺、雲友好、開發迅速的特質,爲此,我下定決心重寫了Apworks。git

全新的Apworks Core應用程序開發框架

新的Apworks Core也是開源項目,該項目依舊基於Apache 2.0許可協議,項目地址是:https://github.com/daxnet/apworks-core。目前仍然還在繼續開發階段,僅實現了原有DDD中的基本概念(實體、聚合、實體鍵、倉儲等),並針對內存併發字典(Concurrent Dictionary)、MongoDB以及Entity Framework Core完成了三種不一樣的倉儲實現,整個框架徹底由.NET Core實現(目前提供net461和Net Standard 1.6兩種編譯),所以,可使用在Windows的經典.NET Framework下,也可使用在Linux的.NET Core中。不只如此,針對ASP.NET Core Web API,Apworks提供了相應的整合與擴展,使得數據服務的開發變得很是簡單方便,這也是本文準備介紹的內容,相信在閱讀本文以後,你將更多地瞭解到Apworks Core的開放性和擴展性,並能體會到在.NET應用程序的開發生態圈中,Apworks Core將會給你帶來更多的幫助。github

演練:使用Apworks Core快速開發數據服務

在開始咱們的Apworks Core開發演練以前,請先完成如下準備工做:shell

  1. 安裝Visual Studio 2017,確保.NET Core和ASP.NET Core的開發功能已經正確安裝
  2. https://www.myget.org/F/daxnet-apworks-pre/api/v3/index.json以及https://www.myget.org/F/daxnet-utils/api/v3/index.json兩個package source添加到NuGet的package source中:

    image
  3. 準備一個MongoDB的數據庫服務器,建議直接下載Windows版本的搭建在本地機器,也能夠在Linux下直接運行mongo的Docker容器,省去了安裝MongoDB的步驟
  4. 若是但願能一塊兒嘗試Visual Studio 2017的Docker功能,還須要確保安裝最新版本的Windows以及Docker for Windows。固然,完成本文的演練並不須要Docker

開發步驟

  1. 首先,新建一個ASP.NET Core的應用程序,名爲CustomerService,經過Manage NuGet Packages添加對Apworks.Repositories.MongoDB以及Apworks.Integration.AspNetCore的引用。添加引用的時候注意選擇https://www.myget.org/F/daxnet-apworks-pre/api/v3/index.json這個package source:

    image

  2. 在CustomerService下新建一個Models目錄,添加兩個類,名稱分別爲Address和Customer,代碼以下:

    public class Address
    {
        public string Country { get; set; }
        public string State { get; set; }
        public string City { get; set; }
        public string Street { get; set; }
        public string ZipCode { get; set; }
    }
    
    public class Customer : IAggregateRoot<Guid>
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public Address ContactAddress { get; set; }
    }

  3. 在Controllers子目錄下,新建一個Controller,取名爲CustomersController,代碼以下:

    public class CustomersController : DataServiceController<Guid, Customer>
    {
        public CustomersController(IRepositoryContext repositoryContext) : base(repositoryContext)
        {
        }
    }

  4. 打開Startup.cs文件,在ConfigureServices方法中,加入如下代碼:

    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc();
    
        services.AddApworks()
            .WithDataServiceSupport(new DataServiceConfigurationOptions
                (new MongoRepositoryContext
                    (new MongoRepositorySettings("localhost", "customer-service"))))
            .Configure();
    }

  5. 一樣在Startup.cs文件中,在Configure方法中,加入如下代碼:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
    
        app.EnrichDataServiceExceptionResponse();
    
        app.UseMvc();
    }

  6. OK, you’re all set! 完成以後,解決方案資源管理器中的項目結構以下,增長了一個Models目錄,以及一個CustomersController:

    image

編譯運行

直接按下Ctrl + F5運行站點,站點起來後,你會發現瀏覽器打開的內容跟標準的新建的ASP.NET Core Web API項目無異,顯示的是由ValuesController的GET方法返回的兩個字符串。不用着急,打開Fiddler,咱們簡單測試一下剛剛新建的Customer數據服務(注意替換一下URL,我本地服務運行在2238端口上):數據庫

  1. POST http://localhost:2238/api/customers

    image

    POST操做成功返回HTTP 201,同時在Response Body中返回了新建的對象Id。
  2. GET http://localhost:2238/api/customers

    image

限於篇幅,此處就不針對全部基本的HTTP操做一一進行測試了。Apworks Data Service默認支持如下HTTP方法,固然,你能夠隨意擴展:json

  1. GET:獲取全部的對象,默認支持服務端分頁,每頁15條記錄,能夠經過http://localhost:2238/api/customers?page=aaa&size=bbb這樣的格式來指定每頁大小以及須要獲取的頁碼
  2. GET {id}:http://localhost:2238/api/customers/{id}:獲取Id值爲{id}的對象
  3. POST {id}:替換Id值爲{id}的對象,替換成功則返回HTTP 204(No Content)
  4. PATCH {id}:更新id值爲{id}的對象,Request Body須要符合Microsoft ASP.NET Json Patch的規範。更新成功返回HTTP 204(No Content)
  5. DELETE {id}:刪除id值爲{id}的對象。刪除成功返回HTTP 204(No Content)

幾個亮點

  1. 開發和配置過程及其簡單,如上所述,五個步驟完成一個數據對象的數據服務開發。流暢接口(Fluent API)配置方式,使得數據服務的開發過程與已有ASP.NET Core Web API的開發過程具備相同的開發者體驗
  2. HTTP GET調用默認支持服務端分頁,分頁連接會經過HAL標記體如今返回結果中
  3. HTTP GET返回直接支持Hypertext Application Language(HAL,官方網站:http://stateless.co/hal_specification.html),返回Content-Type爲application/hal+json。它是經過個人另外一個開源項目https://github.com/daxnet/hal 實現的,HAL項目在.NET Core下完整、全面地實現了HAL規範,而且經過流暢接口(Fluent API)的方式,提供了較好的開發者體驗。經過Apworks Core開發數據服務時,開發者能夠經過設定DataServiceConfigurationOptions參數,選擇是否須要HAL支持,還能夠擴展HalBuildConfiguration類型,以實現HAL返回結果的自定義
  4. 倉儲實現能夠選擇使用In-Memory Concurrent Dictionary、MongoDB以及Entity Framework Core,整個技術棧徹底跨平臺。若是使用Entity Framework Core,目前EF Core對SQL Server、PostgreSQL以及SQLite的支持都不錯,對於Oracle等也有相應的Provider支持,所以,能夠選擇各類不一樣的關係型數據庫來基於Apworks Core快速實現數據服務
  5. 加入EnrichDataServiceExceptionResponse方法可使得當錯誤發生時,數據服務的返回結果將包含更爲準確的錯誤代碼和錯誤信息

對於三種目前支持的倉儲的使用方式、HAL返回結果自定義,以及數據服務的擴展這些內容,我從此再慢慢介紹吧,這裏就很少說了。api

總結

如今,Apworks Core僅僅是剛剛開始,接下來還有很長的路要走,單從數據服務和ASP.NET Core的整合這部分,還須要更加豐富的功能,好比API的幫助頁面、查詢條件和排序條件的指定等等。查詢條件的支持我打算使用我遷移的一個開源的.NET語法分析框架:Irony項目來完成。以後,我仍是會像往常同樣,基於Apworks Core實現一個完整的應用案例,來演示Apworks Core各方面的功能。瀏覽器

另外一方面,Apworks Core的項目分支策略和持續集成也是能夠拿來分享的。我沒有開放Apworks Core持續集成系統,但任何人均可以經過項目的Github主頁瞭解到最新構建的狀態,也能夠看到最新preview和release版本的package source。Apworks Core同時在Windows Server和Ubuntu Linux下完成編譯,編譯徹底採用Powershell腳本完成,所以,對於Linux系統,須要首先安裝Powershell。這些內容我也會爭取抽空跟你們作介紹。安全

最後,仍是那句話,你們多多交流,多提寶貴意見吧。我爭取作得更好。Winking smile服務器

相關文章
相關標籤/搜索