Orchard中大量使用了依賴注入,而實現依賴注入的組件就是Autofac,它在Orchard中扮演者非常重要的角色,多租戶如是,模塊如是,工作區也如是。今天就來講講Autofac在Orchard中的應用。
從OrchardStarter認識Autofac
OrchardStarter中向Ioc容器中注冊了大量的服務,在此中的服務也是“root”域,根域。
Module注冊
builder.RegisterModule(new CacheModule());
這段話代表了注冊一個Module,我們看看CacheModule內又是什么內容。

CacheModule
Load方法:入口
AttachToComponentRegistration方法:事件通知
首先在Load方法內將DefaultCacheManager注冊為ICacheManager並且是瞬態的。
在AttachToComponentRegistration方法中判斷如果其他服務需要服務類型為ICacheManager的服務,則在該服務准備前將ICacheManager服務解析並賦給調用服務。
這邊有意思的是Autofac默認支持構造函數注入,為什么還要寫這么一段復雜的代碼呢?我們來看一看DefaultCacheManager這個類。

Code
可以看到DefaultCacheManager的構造函數有類型為Type的參數componet和類型為ICacheHolder參數的cacheHolder。
而cacheHolder在OrchardStarter中被注冊
builder.RegisterType<DefaultCacheHolder>().As<ICacheHolder>().SingleInstance();
而component的參數沒有找到在哪被注冊。
聰明的人可能已經猜到了AttachToComponentRegistration方法內的內容就是為了傳入這個類型為Type名稱叫component的參數。。可真不容易啊。
這個方法中他把需要使用到ICacheManager服務的類型當作component傳給了DefaultCacheManager,至於為什么我們后面在做分析。
類型注冊
簡單的類型注冊
builder.RegisterType<DefaultHostEnvironment>().As<IHostEnvironment>().SingleInstance();
同時注冊多個服務
builder.RegisterTypes(new[] { typeof(WalmartShop), typeof(CarrefourShop) }).As<IShop>();
生命周期
在Autofac中常用的4種生命周期分別是:瞬態、單例、當前域單例、指定域下單例、某一個對象下的共享域。
其實說白了就只有2種:瞬態和單例,因為Autofac支持子域(子容器)所以才衍生出很多種的生命周期,除上之外官方還提供了在當前請求單例等擴展。
瞬態
每一次解析服務時服務實例都是一個新的實例。
單例
每一次解析服務時如果服務以及被創建則直接返回否則創建一個實例並返回。
域
Autofac中的域非常的驚艷。默認的域Tag為”root”。
在Autofac中有一個概念跟面向對象很像,子域可以擁有根域的服務而根域不可以擁有子域的服務,是不是跟oop中的子類跟父類很像。
一個小小的Demo
參數注入
這邊其實是對服務的構造函數進行注入。
一個簡單的Demo
服務類
入口
服務Key
如果我們同時將WalmartShop和CarrefourShop注冊為IShop我們要怎么區分調用的服務呢?別擔心Autofac考慮到了。
一個簡單的Demo
Named其實就是Keyed的重載,反編譯代碼就可以看到兩者唯一的區別就是Named方法限制了參數必須為string類型而Keyed方法則不限制參數類型為object。
隱式關系類型
Lazy
Owned
Func
IEnumerable、IList 、ICollection
Meta
IIndex
一個簡單的Demo
服務類
入口
寫在最后
這邊講了OrchardStarter中常用的注冊方式,對后面的內容有很大的作用,后面還會涉及Autofac中更多的東西,會根據章節進行講解。
為了本系列的讀者有更好的交流環境提供QQ群一個:299744835