文章目錄:《從入門到放棄,.net構建博客系統》
上一篇中有講到項目啟動時會進行ioc的依賴注入,但具體是怎么注入的呢?我們先一步步往下走
一、注冊autofac配置
首先bootstraper會進行初始化,接着將當前mvc控制器工廠改為AutofacControllerFactory。

1 public class AutofacConfig 2 { 3 /// <summary> 4 /// 負責調用autofac框架實現業務邏輯層和數據倉儲層程序集中的類型對象的創建 5 /// 負責創建MVC控制器類的對象(調用控制器中的有參構造函數),接管DefaultControllerFactory的工作 6 /// </summary> 7 public static void Register() 8 { 9 Bootstrapper boot = new Bootstrapper(); 10 boot.Start(); 11 12 //將MVC的控制器對象實例 交由autofac來創建 13 ControllerBuilder.Current.SetControllerFactory(new AutofacControllerFactory()); 14 } 15 }
二、bootstraper開始注冊服務
在注冊服務前,我們先定義一個容器生成器ContainerBuilder,用以注冊服務;接着我們會獲取當前項目所有引用的程序集,對其中的類型進行判斷,如果符合條件就會注冊進去。那哪些類型會注冊進去呢?
有三種:
1. IDependency,倉儲層和服務層的接口都繼承該接口,注冊的服務會在容器每次resolve的時候,生成一個新對象
2. ISignleton,日志和緩存接口繼承該接口,每次解析都會返回統一對象,即單例對象
3. Module,其中暴露了ContainerBuilder對象,由模塊自定義注冊方式,項目中webapp層有個MvcControllerModule,用於將所有實現IController給注冊進去

1 public void Start() 2 { 3 Type baseType = typeof(IDependency); 4 5 // 獲取所有相關類庫的程序集 6 Assembly[] assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray(); 7 8 containerBuilder.RegisterAssemblyTypes(assemblies).Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract) 9 .AsImplementedInterfaces().InstancePerDependency();//每次解析獲得新實例 10 11 Type singletonType = typeof(ISignleton); 12 containerBuilder.RegisterAssemblyTypes(assemblies).Where(type => singletonType.IsAssignableFrom(type) && !type.IsAbstract) 13 .AsImplementedInterfaces().SingleInstance();// 保證對象生命周期基於單例 14 15 containerBuilder.RegisterAssemblyModules(assemblies);//所有繼承module中的類都會被注冊 16 17 var container = containerBuilder.Build(); 18 ContainerManager.SetContainer(container); 19 }
依賴注冊好后,會生成IOC容器,接着將容器管理器的IOC容器設置為該容器,以后所有的服務的解析可以通過管理器來解析。
三、自定義Autofac控制器工廠
第一步中我們將控制器工廠改為AutofacControllerFactory,這個控制器工廠重寫了GetControllerInstance,主要在解析控制器類型時,用ContainerManager去解析控制器類型,這樣就能把控制器中的依賴給注入進去。

1 protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 2 { 3 if (controllerType == null) 4 { 5 return base.GetControllerInstance(requestContext, controllerType); 6 } 7 8 return ContainerManager.Resolve(controllerType) as IController; 9 }
Git源碼:https://github.com/Halifa/TonyBlogs
如本文對您有幫助請移步右下角,推薦本文,謝謝大家的點贊,因為您的支持是我最大動力