通常來講,一個現代化的網站加載流程是這樣的:程序集加載後,咱們會初始化 IOC 容器,以便於接下來解析對象用。html
咱們插件式的開發,這一步更爲重要。這是由於在開發階段,這些程序集以及 IOC 配置都是分屬於多個解決方案的,在部署前極可能尚未連調。如何在集成在一塊兒後,保證起碼的可用性,是很關鍵的一個步驟。研究稍微深一點的同窗,應該很清楚 WebApi 框架自己就集成了一個 IOC 框架用於對象的生成。咱們要作的工做就是在此基礎上擴展,把咱們要額外注入的東西添加進去。web
IOC 容器選型:Unity
選用 Unity 無可厚非,公司一直在用而且也沒什麼想換的意思。在第一篇文章裏,@elder 說 MEF 不錯,可是大環境下,確實沒見過有人在用。包括微軟自家的 MVC 和 WebApi,基本思想都是實現 CommonServiceLocation
。若是有企業級的應用在使用 MEF,不妨經過私信告訴我。我也想看看這個集成在 .Net 4 中的微軟親兒子,究竟是騾子仍是馬。編程
無論怎麼說,多一種選擇老是沒錯的。至於其它的 IOC 框架,從對 CommonServiceLocation
作適配上來看,基本上都是大同小異,只是獲取類型註冊的方式有所不一樣而已。markdown
這裏我選用現成的 Unity.WebApi
組件將 WebApi 自身的 IOC 容器擴展到 Unity 中(反編譯後能夠發現就兩個類,直接把代碼拷貝出來,貼到項目裏也是能夠的)。框架
容器註冊項加載約定
對於一個 IOC 容器來講,經過配置文件加載註冊項都是不可或缺的。連 Ninject 這種奇葩,都有第三方對其擴展了配置文件支持。在編程中,我我的特別討厭不想幹的代碼侵入,因此通常我會把 IOC 的注入寫在配置文件中:一方面代碼乾淨了,另外一方面,一個簡單的配置修改,就能夠不用從新編譯代碼了,這不就是 IOC 的本質嗎?網站
配置文件能夠屢次附加配置到一個 IOC 容器實例上很必要,這樣我就能夠連續把多個配置文件的註冊項添加到一個實例上。事實上,IOC 容器的實例,全局有且只有一個的時候纔有用。回到我們的 Unity 上面,很不幸的是,Unity 支持這個要求,呵呵。url
額外的,爲了項目總體上一致,我爲 Unity 的配置文件約定:spa
- Unity 配置文件名稱爲
unity.config
。 - 存放路徑爲:相對當前程序集所在目錄的
Configuration\unity.config
,這樣只須要調整生成時老是複製就能夠了。
注:這裏若是你想靈活一些,能夠在上一節的配置文件中添加你的 Unity 配置文件路徑設置信息。插件
部分源代碼:天然語義
額外的,在 Global 中須要用 Unity.WebApi 把擴展點掛接上。下面是 IOC 加載各個模塊配置的事情代碼:3d
public interface IContainerConfiguration
{
object Config(object container);
}
public class DefaultContainerConfiguration : IContainerConfiguration
{
public object Config(object container)
{
var data = new List<string>();
data.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configuration\\unity.config"));
foreach(var item in DynamicModule.Instance.Modules)
{
data.Add(Path.Combine(item.BaseDirectory, "Configuration\\unity.config"));
}
}
}
補充:程序集加載
上一節寫完之後,有人私信問我加載順序的問題。在這裏補充一下,程序集的加載和順序是無關的:我能夠先加載接口的實現程序集,再加載接口程序集。可是還有一些須要注意的地方:
- 程序集加載時,首先加載的程序集 B 若是引用了後續加載的程序集 A,加載不會產生錯誤。
- 後續被引用的程序集 A 被加載後,先前加載的程序集 B 中的類型就能夠正常訪問了。
- 在後續程序集 A 加載以前,若是有使用 B 中的程序集,就會提示出錯;後續程序集 A 加載後,這個錯誤仍將繼續存在,且一直存在。
全部正確的作法是:程序集加載能夠無序進行,可是必定要加載所有程序集後,再進行後續操做。