Autofac是一款IOC框架,比較於其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很輕量級性能上非常高。
源碼下載地址https://github.com/autofac/Autofac
- 控制反轉(IoC/Inverse Of Control): 調用者不再創建被調用者的實例,由autofac框架實現(容器創建)所以稱為控制反轉。
- 依賴注入(DI/Dependence injection) : 容器創建好實例后再注入調用者稱為依賴注入。
安裝Autofac
Install-Package Autofac
1. 掃描類型 RegisterAssemblyTypes(接受1個或者多個程序集的數組),程序集必須是public的
1.1 過濾類型:Where()
builder.RegisterAssemblyTypes(Assembly.LoadFile(servicesDllFile))
.Where(t => t.Name.EndsWith("Services"));
1.2 排除類型: Except()
builder.RegisterAssemblyTypes(Assembly.LoadFile(servicesDllFile))
.Except<myType>(ct =>ct.As<ISpecial>().SingleInstance());
AsImplementedInterfaces() : 表示注冊的類型,以接口的方式注冊,但不包括IDisposable接口
builder.RegisterAssemblyTypes(Assembly.LoadFile(servicesDllFile))
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
AsClosedTypesOf(open):可分配給注冊類型一個接近開放泛型類型的實例
builder.RegisterAssemblyTypes(Assembly.LoadFile(servicesDllFile))
.AsClosedTypesOf(typeof(IRepository<>));
AsSelf() :默認: 注冊類型本身 - 當重寫其他服務默認規范時非常有用
builder.RegisterAssemblyTypes(Assembly.LoadFile(servicesDllFile))
.AsImplementedInterfaces()
.AsSelf();
2. 掃描模塊 RegisterAssemblyModules() 冊方法執行,它的名字是什么,就執行哪個,它通過Autofac 模塊提供的程序集掃描,創建模塊實例,然后使用當前container builder 注冊他們。使用System.Web.Compilation.BuildManager中的GetReferencedAssemblies()方法,會得到一個引用程序集列表,
var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();
注入方法一:
var builder = new ContainerBuilder();
builder.RegisterType<TestService>();
builder.RegisterType<TestDao>().As<ITestDao>();
return builder.Build();
注入方法二:
為了統一管理 IoC 相關的代碼,並避免在底層類庫中到處引用 Autofac 這個第三方組件,定義了一個專門用於管理需要依賴注入的接口與實現類的空接口 IDependency:
/// <summary>
/// 依賴注入接口,表示該接口的實現類將自動注冊到IoC容器中
/// </summary>
public interface IDependency
{ }
這個接口沒有任何方法,不會對系統的業務邏輯造成污染,所有需要進行依賴注入的接口,都要繼承這個空接口,例如:
業務單元操作接口:
/// <summary>
/// 業務單元操作接口
/// </summary>
public interface IUnitOfWork : IDependency
{
...
}
Autofac 是支持批量子類注冊的,有了 IDependency 這個基接口,我們只需要 Global 中很簡單的幾行代碼,就可以完成整個系統的依賴注入匹配:
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(Repository<,>)).As(typeof(IRepository<,>));
Type baseType = typeof(IDependency);
// 獲取所有相關類庫的程序集
Assembly[] assemblies = ...
builder.RegisterAssemblyTypes(assemblies)
.Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract)
.AsImplementedInterfaces().InstancePerLifetimeScope();//InstancePerLifetimeScope 保證對象生命周期基於請求
IContainer container = builder.Build();
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開發。
參考鏈接:
autofac 創建實例方法總結:http://www.cnblogs.com/manglu/p/4115128.html
AutoFac使用方法總結:Part I:http://niuyi.github.io/blog/2012/04/06/autofac-by-unit-test/