WebApi 插件式構建方案

WebApi 插件式構建方案

公司要推行服務化,不可能都整合在一個解決方案內,於是想到了插件式的構建方案。最終定型選擇基於 WebApi 構建服務化,之因此不使用 WCF 是由於不符合 RESTful 風格,而且對 OData 開源查詢協議支持不是太好。程序員

插件化構建的兩種思路

  1. 不進行二次開發,直接把編譯完成的程序集放到 bin 目錄便可。
  2. 針對程序集尋址作擴展,把插件程序集放到 bin 的二級目錄。

在這裏,我對二者的優缺點進行一下分析:web

  • 第一種方案:若是是臨時方案我沒有意見,畢竟是過渡用的,業務爲重嘛。可是,做爲萬人敬仰的程序員,你他孃的也太懶了吧!那麼多程序集放在一塊兒,萬一堆太多堆過久生蛆了腫麼辦?萬一哪家小朋友不聽話,把本身埋了腫麼辦?
  • 第二種方案:嗯,還得開發,並且弄很差還會把項目搞砸!後果很嚴重,領導很生氣!腫麼辦?無奈 + 無解。。。

其實不用那麼麻煩,用別人開發的一套成熟的東西就好辦了。沒有?好,坐下來,聽我慢慢說。數據庫

WebApi 啓動流程簡介

任何基於 Http 的服務端程序,啓動管道和請求響應管道指定是跑不了的。api

  • 啓動管道是服務自我配置的過程:這個時候 XML 配置和一些默認的約定就起做用了,好比 IOC 容器 Unity 啓動時會從 unity.config 文件中讀取映射配置,WebApi 框架缺省狀況下會尋找從 ApiController 繼承而且類名稱結尾是 Controller 的類做爲控制器。
  • 請求響應管道是服務器接到客戶端請求後的處理流程:能夠想象一下咱們公司裏的審批流,你要請假了,必須得小組長先批准,而後總監批准,接着人力審覈,財務扣錢等等。在這裏,通常會首先進行認證,受權和附加信息獲取等流程,最後纔會交給咱程序員寫的邏輯去處理。

注:對於自承載的服務,也會有一個相似的流程。服務器

流程一:獲取程序集列表

掛載在 IIS 上時,會從 BuildManager 中獲取程序集列表:這個列表是通過 ASP.NET 程序底層優化過的,可以獲取全部的程序集信息。自承載時,只是簡單粗暴地調用 Assembly 類的靜態方法,估計會有一些問題,我沒試過,這裏不作討論。考慮到絕大多數人仍是使用 IIS 掛載的,說太詳細沒什麼意義,我也沒那個精力。框架

.Net 4.0 時代,ASP.NET 程序啓動時,能夠給程序集加上一個 Attribute(PreApplicationStartMethod),能夠添加一些啓動後不能變動的工做。這裏咱們要作的工做,就是把那些不在 bin 根目錄的程序集加載進去,經過 AddReferencedAssembly 靜態方法添加便可。優化

注意:網站

  • 不要加載一個程序集的不一樣版本,這會對程序的運行產生不可預知的影響。
  • ASP.NET 的某些變量還沒初始化,你的某些想法不會成立。

這裏,我在加載了程序集的基礎上,又公開了一些模塊的元數據信息:ui

  • 插件的初始配置:插件名稱、路徑、啓動順序、可用性、插件可見性、數據庫鏈接字符串。
  • 插件運行須要加載的程序集列表。

這些信息使得我在服務運行後,有了較大的定製空間。好比後面根據模塊名稱產生模塊前綴 RESTful 服務;還有在另外的管理網站,統一管理服務的幫助系統等,源數據都是以其爲依據的。插件

注:插件初始配置中,可用性決定了這個插件是否加載,這是總開關。

流程二:IOC 容器初始化

現代的網站,很難想象若是沒有 IOC ,程序的複雜性會提高多少。因此我把 IOC 的初始化提高到最重要的位置。可是考慮到 IOC 容器不一樣人會有不一樣的選擇,我這裏只依照微軟 Unity 爲藍本作講解。至於各個插件的使用上,統一採用 CommonServiceLocator 作 IOC 容器接口。

這裏我解釋下爲何使用 CommonServiceLocator 作使用的接口方案:

  • 接口穩定:君不見微軟這麼多年來,歷來沒更新過這貨嗎?
  • 適配器豐富:能夠這麼說,.Net 世界的 IOC 容器,幾乎都有針對的適配器。因此說,不用考慮未來更換 IOC 容器實現時,各個插件的更新問題。這根本就不是事!
  • 公司一直在在用 Unity ,並且還專門作了接口實現,沒得選沒的說,不解釋。

根據流程一提供的插件路徑,約定 Configuration\unity.config 爲存儲接口映射的地方,在程序啓動時依據插件啓動順序,逐個加載映射信息。

這一步完成後,就能夠直接經過容器獲取接口的實例了,很好的隔離了契約和實現,同時也讓咱們的程序趨於簡單化,不用再用複雜的抽象工廠了。話說使用抽象工廠的配置也不比配置 IOC 容易,還都是私有的配置,一個個實現都不一樣,新人剛進入環境就是一頭霧水。

流程三:集成加載數據庫鏈接字符串

每一個插件通常都會有本身的數據庫訪問功能,由於是插件化的方案,因此此時數據庫鏈接字符串就很很差處理:生成後就不用再考慮鏈接字符串;插件本身放着就好,不用拷貝到指定的地方去。

很幸運,.Net 提供了一個叫作反射的東西,容許作一些工做後更新到 .Net 框架自帶的鏈接字符串容器中,這樣咱們就能夠在運行時不用管這個叫數據庫鏈接字符串的東東了。惟一注意的一點就是:各個插件提供的數據庫鏈接字符串名稱不能有相同的。我相信這不是什麼問題!

注:這個功能的實現依賴於流程一的插件初始配置,須要添加一個鏈接字符串所在文件的絕對路徑的東東,以便於讓系統指導從哪裏獲取這些鏈接字符串。每一個模塊都要配置一個,固然不用數據庫操做的模塊能夠忽略。

流程四:重寫的控制器獲取工廠

缺省的控制器獲取工廠,只會根據約定產生諸如 {controller}/{action}/{id} 這類的地址,那要咱們插件如何是好?萬一兩家寫的地址同樣呢?小朋友會不會找不到家了呢?在前面加上 {module} 可好?

好吧,咱們假設方案是可行的,咱們註冊 {module}/{controller}/{action}/{id} 這樣的路由,那就須要能解析這個路由的工廠才行啊,否則咱們得不到控制器,談何執行?

沒什麼可說的了,實現接口就行了,參考缺省實現,咱們只須要把查找的 Key 加上模塊名字就行了。

流程五:沒什麼可說的了

運行你的 WebApi 服務吧,網站不用引用你控制器項目,須要的時候把生成好的程序集放到 IIS 網站下你的目錄就行了。這裏推薦放在 bin 目錄下面,好處是在你更新 bin 下面的文件時,IIS 會從新啓動這個網站。

相關文章
相關標籤/搜索