在 .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.WebApi
Step 3 - 在業務庫中編寫控制器
為 Users Library 添加一個 Controllers 的目錄,並編寫你的控制器
[ApiRoute("hello")] public class HelloController : ApiController { [Route] public string Get() { return "HelloWorld!"; } }
Reface.AppStarter.WebApi 包含了編寫一個 WebApi 的所有依賴項。
因此你只要通過 Nuget 添加了 Reface.AppStarter.WebApi 就可以編寫屬於你的 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》
有關 事件總線,會在后面的文章中向大家介紹。