零基礎ASP.NET Core WebAPI團隊協做開發

零基礎ASP.NET Core WebAPI團隊協做開發

相信你們對「先後端分離」和「微服務」這兩個詞應該是耳熟能詳了。網上也有不少介紹這方面的文章。我這裏提這個是由於接下來我要分享的內容和這個有些關聯。html

 

隨着前端應用場景的繁榮,用戶體驗需求的提升,原先傳統的後端渲染頁面返回給前端展現的模式面臨挑戰。後端工做除了處理數據邏輯還得適應界面UI的業務,愈來愈不堪負重。前端的重要性逐漸體現出來,在這種狀況下使用先後端分離模式開發的逐漸增多。前端

 

前端框架(好比Vue/Angular/React)的發力,大廠的推廣使用,先後端分離已經很成熟。包括傳統信息化這塊之前使用傳統WebMVC模式的開發BS應用有些都逐步轉爲先後端分離模式。特別是開發人員分工以後專一作好各自的工做,效率更高,作出來的產品也就更好。git

 

1、應用場景github

1瀏覽器端(Vue/Angular/React+服務端API後端

2桌面客戶端(mfc/winform/wpf+服務端APIapi

3移動客戶端(各類App/App內置瀏覽器)+服務端API瀏覽器

4、其餘終端(大數據展現平臺/報表展現平臺)+服務端API前端框架

 

客戶端愈來愈強調輕量化,交互體驗,不在知足於能用。服務端端只管提供API數據,這樣業務邏輯大多在服務端處理,隨着需求增長服務端的模塊會愈來愈多。可是有些接口是共用的,有些是根據業務變更的,還有的API新舊版本過渡更新替換等等是服務端api要考慮的事情。設計好API開發框架面靈活應對這麼多場景就頗有必要了。框架

 

原先可能會作一個單體式應用,把全部用到的接口都加進去。但這樣粒度很粗,若是某個場景下只使用了部分接口,那也得把這整個應用部署,沒法作到按需添加。還有就是可能要修改其中部分方法,須要總體從新編譯發佈。這都存在可能影響其餘模塊的風險。前後端分離

服務端任務量大了,怎麼分工?這個時候單體明顯已經不適用了。這裏就引出了微服務。對微服務可能每一個人有不一樣的理解,但有一點是有共識的,就是把一個大的單體式應用根據功能模塊拆分,這樣粒度細分以後不少接口就能夠共用。以後的修改增長都是能夠按需發佈部署,局部出現問題不會影響總體。

 

這個服務的粒度怎麼拆分也是須要慎重考慮的問題。除了功能拆分還得考慮人員匹配。

案例場景:一個系統有10個子系統(模塊),每一個子系統(模塊)又有10個功能,每一個功能再具體又可能有20左右的方法代碼。

 

這個案例,最後大概有2000個方法代碼。

若是開始安排10人的團隊開發,中途由於項目緊急再增長了10我的進來,總共變成了20人,項目組怎麼作才能快速適應這種人員變更。

有時候不是人越多越能作好事情,在人員增長狀況下除了增長溝通協調成本,實際狀況會遇到新加的人蔘與進來的門檻很高,不能快速着手展開工做,有時候還會出現不知道從何入手的困境。這就是由於拆分的不合理,任何的改動可能會影響到他人。這樣雖然爲了趕進度加人了,但實際的效果卻不是很理想。

 

2、功能拆分分析

怎麼拆分這有兩個極端例子

1、粒度最粗,所有在一個解決方案(極端例子,相似單體式應用,適合一人開發)

2、粒度最細,細分到每一個方法一個解決方案(極端例子,實際確定不會這樣作)

 

實際項目中功能拆分就是在這兩個極端狀況之間找適合的平衡點。具體拆分到多大的粒度,這個就只能是根據具體項目狀況具體分析了。可是微服務多是建議往細的方向拆。

若是是項目型的會發現若是拆的太細,上線一套系統要帶N個接口,運維實施都很麻煩;若是是作平臺型的產品可能就是有限的幾套系統,不會隨着項目鋪開太多定製化。也就沒有了項目型裏面的常常部署實施等繁瑣的問題。

好比上面的案例,通常都是先根據子系統拆分,具體到每一個子系統,有一人或多人開發也有後期臨時加入的狀況。每一個子系統一套接口仍是比較合適的。

 

實際狀況項目型比較多,考慮實施運維狀況拆分的粒度不會太細,讓實施去部署太多業務接口會把他們逼瘋。若是有和我相似狀況的下面的方案提供了一種解決辦法。開發時候能夠橫向任意擴展,新加入的人員分配任務清晰,不用擔憂有耦合衝突。發佈部署也不會由於粒度太細,增長部署工做量。總結就是插件式開發,微服務部署。

 

咱們都知道vs裏面創建一個解決方案,兩三個開發人員在同一個解決方案裏面開發,只要協調好還行,若是再加入人員,參與的開發人員一旦多了,就算分工好作各自模塊,但仍是會存在一個些衝突,好比增長文件,增長引用等等都會引發項目文件或者解決方案文件衝突問題。並且這種狀況代碼權限還很差細分控制。

 

最好的方式是每一個開發人員作的事情都在本身的解決方案裏面,只要是公共使用的引用協調好你們使用統一的版本,其餘的本身徹底可控,徹底不用擔憂影響他人,或者他人的修改影響本身。

 

你們能夠看下這個 github上面dotnet基礎類庫 如圖1。

 

1

 

這是dotnet基礎庫的源碼,每一個基礎類庫都是單獨一個解決方案維護,隨便點一個進去看下,如圖2

 

2

每一個類庫都有獨立解決方案文件。

 

微軟確定有更好的方式去管理,但從這裏能夠看出,獨立開發維護的優點。

 

3、接口項目準備

 

前面分享過一篇《零基礎ASP.NET Core MVC插件式開發》的文章,那邊文章其實也就是強調團隊開發的時候能作到儘可能獨立,能夠橫向擴展,項目靈活變更增長開發人員能夠快速參與,開發以後能彙總到一個個的子系統,最後完成總體開發。在這裏API的開發也能夠使用相似方案,由於API沒有視圖部分,處理起來MVC簡單。

 

接下來重點介紹該方案在API開發中的使用。開始這部份內容以前先簡單介紹我這邊API項目開發總結的兩個共性問題:

一、使用swagger顯示API文檔(nuget 引用 Swashbuckle.AspNetCore

由於API是沒有試圖的,爲了可視化,以及方便測試,使用swagger做爲API的展現界面。具體使用看下面提供的demo代碼

 

二、使用版本控制API版本號(nuget 引用Microsoft.AspNetCore.Mvc.Versioning

版本控制對API也是一樣重要,看BAT大廠提供的API都是有版本控制的,要向他們看齊。實際應用中,程序不可能維持一套最新,有時候新舊版本須要過渡,因此須要有版原本區分。這裏使用微軟提供的版本控制。具體使用看下面提供的demo代碼

 

 

這兩個使用這裏就不細說了,穿插下面主題作些簡單介紹,具體看案例demo就能夠。

 

4、接口插件式開發

 

回到咱們的主題,這裏重點介紹下一個子系統(模塊)任務拆分與人員分工

 

項目組接下一個項目,通常有個開發組長,着手模塊劃分而且開發任務分工

組長(公共部分接口+核心功能模塊接口)

組員1:細分的模塊插件1接口

組員2:細分的模塊插件2接口

組員3:細分的模塊插件3接口

......

......

 

對於的解決方案結構,具體命名本身能夠根據喜愛本身自定義。

 

Agile.ModuleName.API  以下圖3

Agile.ModuleName.Plug1.API 圖下圖4

Agile.ModuleName.Plug2.API

Agile.ModuleName.Plug3.API

......

......

 

 

3

 

4

 

Demo使用的是vs2019Asp.net core 2.1

 

注意:若是一個模塊裏面接口比較多,一個解決方案裏面不適合團隊開發。因此對這種接口功能比較多,拆成各個插件方便團隊開發,最後發佈的時候合併到一塊兒。可是若是這個模塊接口不是不少,就不必過分設計爲了插件化而拆開。

 

每一個獨立開發的都是vs裏面創建的標準ASP.NET Core WebAPI項目,這裏主項目和各個插件項目沒有從屬關係,徹底平等API項目開發,最後只是能夠匯合到主項目做爲一個站點發布交付。各自獨立調試運行各自開發功能模塊,測試沒問題發佈彙總到主項目,部署運行,以後哪一個接口問題只須要找到對應的模塊修改,徹底隔離開,不用擔憂修改會影響其餘正常使用的模塊。

 

 

主項目解決方案結構,如圖5

 

5

 

v1v2裏面的是有版本控制的,放在外面的就不須要版本控制。

還有Extensions文件夾裏面兩個類也是爲了版本的顯示作處理,具體看Startup.cs裏面代碼,如圖6

 

6

 

搭建好以後,主項目運行,選擇v1版本顯示如圖7

 

7

 

若是選擇v2,顯示如圖8

 

8

 

經過上面兩個切換,應該看到無論選擇v1仍是v2下面不受版本控制的都會顯示。

 

 

若是把圖4的代碼註釋掉,看下運行效果,如圖9

 

 

9

顯示就這樣,不能根據swagger選擇,直觀的顯示是v1仍是v2。這個就是RemoveVersionFromParameterReplaceVersionWithExactValueInPath兩個類的做用。

 這兩個類的代碼以下

public class RemoveVersionFromParameter : IOperationFilter
    {
        public void Apply(Operation operation, OperationFilterContext context)
        {
            if (operation.Parameters.Count > 0)
            {
                var versionParameter = operation.Parameters.FirstOrDefault(p => p.Name == "version");
                operation.Parameters.Remove(versionParameter);
            }
        }
    }


public class ReplaceVersionWithExactValueInPath : IDocumentFilter
    {
        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
        {
            swaggerDoc.Paths = swaggerDoc.Paths
                .ToDictionary(
                    path => path.Key.Replace("v{version}", swaggerDoc.Info.Version),
                    path => path.Value
                );
        }
    }

 

到這裏主項目API運行正常,接下來看下插件項目API

插件1項目結構,和主項目相似,如圖10

 

10

單獨運行下這個插件1項目,效果如圖11

 

11

 

這裏做爲插件API項目一樣有一點要注意,不要出現和其餘插件或者主項目同名的路由(versioncontrolleraction三個徹底同樣,分工以後各自命名規範估計這種狀況也不會出現,主要仍是注意避免合併以後路由重名問題)。

 

這裏先把插件1編譯的dll放到主項目的運行目錄來,如圖12

 

12

 

而且在主項目的Startup.cs裏面增長這段代碼,如圖13

 

13

 

運行看下效果,如圖14

 

14

 

匯合成功,插件1API能展現出來,測試也正常,測試就不截圖了。

同理,插件1,插件2...等等也是同樣處理。開發階段,各自開發的功能都是能夠獨立調試運行的。有沒有主項目對各自開發的不影響。

 

 

 

 

5、問題總結

 

若是插件項目裏面引用了一個第三方的程序集,如圖15

 

15

 

引用一個測試類庫,在Plug1NoVerControllerGet方法裏面寫一個測試代碼,如圖16

 

16

在插件項目單獨測試,運行正常。

再把插件1相關文件拷貝到主項目,這時候多了個插件項目本身引用的OtherLib.dll,如圖17

 

17

 

正常運行,如圖18

 

18

 

測試下剛纔插件1裏面用到OtherLib類的接口,看效果如圖19

 

19

 

汗,竟然報錯了,提示FileNotFoundException,可是看上面的錯誤信息截圖提示找不到OtherLib.dll文件。OtherLib.dll這個文件明明在這個目錄有的。查了相關資料都說是.net core的加載機制變了,但仍是沒理解透徹,不知道.net core3.0會不會解決這個問題。但願有大神看到能夠解惑下這個問題。不過這裏我使用一種方式能夠解決這個報錯,在主程序這裏加這段代碼。在註冊插件項目以前,遍歷全部dll,作一次加載就能夠了。如圖20

 

20

 

須要在註冊插件以前,把全部dll文件這樣加載一遍,就能夠了。

再運行,測試就正常了,如圖21

 

21

 

 

6、發佈運行

各個獨立開發的插件API,各自獨立開發調試正常以後,發佈出來。

好了,插件1,插件2...等等各自都開發好了,各自模塊調試沒問題,最後彙總到主的項目來,基本也就沒什麼問題了,而且還能夠做爲一個站點部署。

這裏的一個站點只是一個接口服務,不要理解成一個系統就這一個接口服務,雖然能夠這樣作,但不建議,部署仍是各個子系統一個服務,這樣數量也不會不少。這裏是指在開發階段對一個子系統(模塊)的N個接口作開發方面的分工獨立開發調試。

子系統(模塊)有N個接口,開發分工以下:

主插件,插件1,插件2,插件3...

所有彙總到主插件的發佈目錄,或者手動拷貝,最後提供一個完成的子系統接口發佈版本,目錄如圖22

 

22

 

一樣命令行運行,或者宿主到iis,這裏命令行運行,如圖23

 

23

 

瀏覽器打開,如圖24

 

24

 

直接swagger測試各個接口,正常。

獨立插件化開發,微服務發佈部署。

 

但願你看了以後有點收穫,代碼程序下面附件提供

Demo程序

相關文章
相關標籤/搜索