控制反轉(IoC/Inverse Of Control): 調用者不再創建被調用者的實例,由autofac框架實現(容器創建)所以稱為控制反轉。
依賴注入(DI/Dependence injection) : 容器創建好實例后再注入調用者稱為依賴注入。
AutoFac是一款IOC框架:
源碼下載地址https://github.com/autofac/Autofac
注入方法一:
1 var builder = new ContainerBuilder(); 2
3 builder.RegisterType<TestService>(); 4 builder.RegisterType<TestDao>().As<ITestDao>(); 5
6 return builder.Build();
注入方法二:
為了統一管理 IoC 相關的代碼,並避免在底層類庫中到處引用 Autofac 這個第三方組件,定義了一個專門用於管理需要依賴注入的接口與實現類的空接口 IDependency:
1 /// <summary>
2 /// 依賴注入接口,表示該接口的實現類將自動注冊到IoC容器中 3 /// </summary>
4 public interface IDependency 5 { }
這個接口沒有任何方法,不會對系統的業務邏輯造成污染,所有需要進行依賴注入的接口,都要繼承這個空接口,例如:
業務單元操作接口:
1 /// <summary>
2 /// 業務單元操作接口 3 /// </summary>
4 public interface IUnitOfWork : IDependency 5 { 6 ... 7 }
Autofac 是支持批量子類注冊的,有了 IDependency 這個基接口,我們只需要 Global 中很簡單的幾行代碼,就可以完成整個系統的依賴注入匹配:
1 ContainerBuilder builder = new ContainerBuilder(); 2 builder.RegisterGeneric(typeof(Repository<,>)).As(typeof(IRepository<,>)); 3 Type baseType = typeof(IDependency); 4
5 // 獲取所有相關類庫的程序集
6 Assembly[] assemblies = ... 7
8 builder.RegisterAssemblyTypes(assemblies) 9 .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract) 10 .AsImplementedInterfaces().InstancePerLifetimeScope();//InstancePerLifetimeScope 保證對象生命周期基於請求
11 IContainer container = builder.Build(); 12 DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
如此,只有站點主類庫需要引用 Autofac,而不是到處都存在着注入的相關代碼,大大降低了系統的復雜度。
1、InstancePerDependency
對每一個依賴或每一次調用創建一個新的唯一的實例。這也是默認的創建實例的方式。
2、InstancePerLifetimeScope
在一個生命周期域中,每一個依賴或調用創建一個單一的共享的實例,且每一個不同的生命周期域,實例是唯一的,不共享的。
3、InstancePerMatchingLifetimeScope
在一個做標識的生命周期域中,每一個依賴或調用創建一個單一的共享的實例。打了標識了的生命周期域中的子標識域中可以共享父級域中的實例。若在整個繼承層次中沒有找到打標識的生命周期域,則會拋出異常:DependencyResolutionException。
4、InstancePerOwned
在一個生命周期域中所擁有的實例創建的生命周期中,每一個依賴組件或調用Resolve()方法創建一個單一的共享的實例,並且子生命周期域共享父生命周期域中的實例。若在繼承層級中沒有發現合適的擁有子實例的生命周期域,則拋出異常:DependencyResolutionException。
5、SingleInstance
每一次依賴組件或調用Resolve()方法都會得到一個相同的共享的實例。其實就是單例模式。
6、InstancePerHttpRequest
在一次Http請求上下文中,共享一個組件實例。僅適用於asp.net mvc開發。