如何將 .NetFramework WebApi 按業務拆分成多個模組
在 .NetFramework 中使用 WebApi ,在不討論 微服務 的模式下,大部分都是以層來拆分庫的 :
- 基礎設施
- 資料儲存層
- 服務層
- WeApi 層
- 一些其它的功能庫
專案結構可能會像下面這樣子
有些人可能會將其中的 資料儲存層、服務層 按業務功能進行垂直拆分,
但是到了 WebApi 這層,就不得不把所向所有業務功能的 Controller 都堆在這兒了。
隨著業務的堆積,WebApi 這層的程式碼量越來越大,耦合性也越來越強,越來越難維護。
…
……
………
…………
這時候,微服務 就出現了。
可是,微服務 給系統所帶來的複雜程度是極高的,
在某些場景下,轉 微服務 可以很好的解決這些問題,但是又會帶來更多的新問題,
所以我們希望有一種模式,即能像 微服務 那樣對程式碼進行垂直切分,又能保持簡單易維護的 單體應用程式 模式。
打算在 單體應用程式 中解決這種趨於 臃腫 問題,我們可以借鑑 微服務 那種 按業務垂直拆分 的思想。
但是與 微服務 不同是,它依然是單啟動程式,這個啟動程式能夠組織出散落在各個模組中的所有 WebApi 並暴露給外部。
換個角度思考,其實就是將業務 模組化 。
微軟維護的 Ochard 框架很好的實現了這些功能,但是使用 Orchard 可能會給你帶來以下問題
- 這是一個非常重型的框架,程式碼量比較大,執行速度不佳
- 幾乎沒有什麼中文的文件( 最多隻能找到 HelloWorld 這樣的淺顯的教程 )
- 官網文件是英文的,對閱讀有較高的要求,而且速度很慢,需要使用正確的閱讀方式
- 系統中充斥著大量的隱匿約束( 在型別名稱上的約束,前端更是使用了大量的 DynamicObject ,很難了解到到底包含了哪些可用 成員 )
....
於是我基於 Reface.AppStarter 開發了一套輕量級的模組化 WebApi 框架 【 Reface.AppStarter.WebApi 】,它實現了以下功能
- 垂直拆分你的 WebApi Controller 至不同的 Library
- 開箱即用的 Controller 建構函式注入
- 具備 Reface.AppStarter 中的 EventBus 和 CommandBus 功能,可以很好的進行模組間的通訊
- 在 啟動模組 決定啟動哪些業務模組
使用 Reface.AppStarter.WebApi 很簡單,它對原來的開發風格幾乎沒有什麼影響,
下面將演示如何使用 Reface.AppStarter.WebApi 將 WebApi 專案拆分至各種模組
Step 1 - 建立空的 WebApi 專案
建立一個 WebApi 專案,但是你不需要在這裡寫任何的 Controller , 它只是你的啟動程式,不需要為它編寫任何與啟動無關的程式碼。
為你的 WebApi 新增 Nuget 引用 Reface.AppStarter 。
Step 2 - 建立業務庫
建立業務 Library ,比如 Users,你將在這個 Library 中實現有關 Users 的所有功能,包括 Controller。
通過 Nuget 引用 Reface.AppStarter.NPI
Step 3 - 在業務庫中編寫控制器
為 Users Library 新增一個 Controllers 的目錄,並編寫你的控制器
[ApiRoute("hello")] public class HelloController : ApiController { [Route] public string Get() { return "HelloWorld!"; } }
Reface.AppStarter.NPI 包含了編寫一個 WebApi 的所有依賴項。
因此你只要通過 Nuget 添加了 Reface.AppStarter.NPI 就可以編寫屬於你的 ApiController 。
如果你需要向 控制器 中注入一些其它的元件,你只要通過建構函式注入即可:
[ApiRoute("hello")] public class HelloController : ApiController { private readonly IHelloService helloService; public HelloController(IHelloService helloService) { this.helloService = helloService; } [Route] public string Get() { return "HelloWorld!"; } }
Step 4 - 編寫業務庫的 AppModule
為你的 Users Library 編寫一個 AppModule 。
在 Reface.AppStarter 框架模式下,每一個 Library 都至少要提供一個 AppModule ,以供給其它模組依賴。
你的 Users 也不例外,
UsersAppModule 需要使用 WebApi 功能,因此 UsersAppModule 要依賴 WebApiAppModule
[WebApiAppModule] public class UsersAppModule : AppModule { }
如果你還需要 自動配置、自動 IOC / DI 註冊裝配,那你也可以根據你的需求新增其它的 AppModule。
Step 5 - 讓你的啟動專案依賴 UsersAppModule
首先,你需要為你啟動專案建立一個 AppModule ,比如 WebAppModule
[UsersAppModule] public class WebAppModule : AppModule { }
然後你需要建立一個 Global.asax ,相信大家應該都知道這是個什麼吧。
修改你的 Global.asax 檔案,使其繼承於 RefaceHttpApplication<T> ,這裡的 T ,就是你的 WebAppModule。
public class MyWebApiApplication : RefaceHttpApplication<WebAppModule> { }
這樣,就會在 Web 應用程式啟動的時候,完成 Reface.AppStarter 中的所有過程。
提示 :
- 這個 RefaceHttpApplication<T> 只是封裝了 AppSetup.Start 的過程,你也可以不繼承此類,並手動完成對 AppSetup 的啟動。
Step 6 - 配置檔案
通過 RefaceHttpApplication<T> 啟動,會以站點根目錄的 app.json 檔案作為 Reface.AppStarter 框架內的配置檔案。
Reface.AppStarter.WebApi 內只有一個 Config 型別,它允許重新定義所有 WebApi 的路由字首
{ "WebApi": { "Prefix": "myapi" } }
你可以通過修改這個 Prefix 來修改所有控制器的字首名稱,( 預設值是 api )。
Step 7 - 執行
執行你的啟動程式吧,並鍵入 /myapi/hello 你就會看到 HelloController 雖然寫在了別的 Library 裡,但是依然可以成功的訪問。
至此就介紹了 Reface.AppStarter.WebApi 中的主要功能。
有關 Reface.AppStarter 相關功能,可以閱讀 《https://www.cnblogs.com/ShimizuShiori/p/12610668.html》
有關 事件匯流排,會在後面的文章中向大家介紹。
關注公眾平臺【清水潭】,可以查閱更多