蝸牛歷險記(二)之Web框架下的Autofac
接上篇所說,本篇主要內容是講述如何使用Autofac來管理整個平臺的生命周期(初級)。
一、簡述
插件式Web開發的同學應該還會記得PreApplicationStartMethod這個Assembly級別的Attribute,它可以在應用程式啟動之初(Web啟動之前)啟動,一般我們用它來做一些插件資源拷貝、插件動態載入的工作。
[assembly: PreApplicationStartMethod(typeof(PreApplicationInit), "InitializePlugins")]
它所指定的代碼:
public static void InitializePlugins() { PluginManager.Current.Initialize();//插件管理器初始化 }
所有資源拷貝完畢,插件也被Assembly.Load完畢後,進入正式環節。我們將在Global.asxc的Application_Start方法中進行IOC的初始化。
二、Autofac初始化
第一步,採用Autofac的模塊化初始化方式來初始化平臺公共模塊
internal static void BuildFrameworkIocEnviroment(){ var builder = new ContainerBuilder(); builder.RegisterModule(new MvcModule()); builder.RegisterModule(new WebApiModule()); builder.RegisterModule(new LoggingModule()); builder.RegisterModule(new EventsModule()); builder.RegisterModule(new CacheModule()); }
第二步,採用自動初始化方式將實現註冊到IDependency,ISingletonDependency,ILifeScopeDependency,註冊結果分別為:每次都重新生成,全局單例,每次請求周期內單例。
var dependency =assemblyTypes.Where(p => (typeof (IDependency)).IsAssignableFrom(p) && !p.IsAbstract && !p.IsInterface).ToArray(); var singleton = dependency.Where((typeof (ISingletonDependency)).IsAssignableFrom).ToArray(); var lifescope = dependency.Where((typeof (ILifeScopeDependency)).IsAssignableFrom).ToArray(); var perdependency = dependency.Except(singleton).Except(lifescope).ToArray(); containBuilder.RegisterTypes(singleton).AsImplementedInterfaces().SingleInstance(); containBuilder.RegisterTypes(lifescope).AsImplementedInterfaces().InstancePerLifetimeScope(); containBuilder.RegisterTypes(perdependency).AsImplementedInterfaces().InstancePerDependency();
三、Autofac的使用
為何需要用Autofac這類的IOC初始化容器?在插件式項目開發和基於介面編程的項目中,插件功能內聚,業務邏輯集中在介面實現上。IOC在這方面不經幫我們管理了對象的生命周期,而且方便地將功能由直接實現到面向介面編程(最常用的做法就是將實現註冊為對應的介面)。
註冊時我們採用了4中註冊方式,在Web項目中應用最多的應該是請求周期內單例,所謂請求周期內單例,就是指,在一個請求到達Web程式域環境內,直到它獲得Response離開應用程式域之間是單例的,而且各個請求互不幹擾。這麼做一是方便數據間的傳輸,二是很大程度上減少對象生成,節約了記憶體的開銷。
如何做到“面向介面”編程?
首先我們定義一個介面以及它的實現。
public interface IService:IDependency { int DoSomeBusiness(); } public class IntService:IService{ public int DoSomeBusiness(){ //do something return 0; } }
然後我們採用構造函數註入的方式使用它:
public class HomeController:Controller{ private readonly IService _service; public HomeController(IService service){ _service=service; } public ActionResult Index(){ var val=_service.DoSomeBusiness(); return View(val); } }
看,這就是最粗顯地面向介面編程了,我們在頁面上要顯示的數據,是通過IService這個介面來實現的,如果業務邏輯改變,我們可以定義新的IService的實現。當然,本例中還是可以很簡單地改造為屬性構造的。
有關Autofac等的框架就簡單介紹到這,博客園有關IOC、Autofac的介紹也有很多,就不細說,這裡主要就介紹我所使用的項目中Autofac使用的部分。下一遍將介紹日誌框架的實現。