這裏主要學習一下Autofac的依賴注入方式
默認構造函數注入
class A { public B _b; public A() { } public A(B b) { this._b = b; } } class B { }
builder.RegisterType<A>(); builder.RegisterType<B>(); using (var container = builder.Build()) { //A的構造方法需要參數b,但是這裏不需要做更多地操作,如果不註冊類型B,這裏a._b=null var a = container.Resolve<A>(); }
如果類型A和類型B都註冊到了autofac中,那麼在通過autofac解析獲取A時,autofac會檢測到A的構造方法中是要一個參數B,而類型B是已經註冊到autofac中的,所以autofac會自動創建b參數,然後傳入A的構造方法中的。這樣,autofac就自動幫我們完成了構造注入的工作
屬性注入
屬性注入的所有注入方式都是在註冊時定義的,不像構造注入那般,可以在Resolve時傳參注入。構造器注入是默認行爲,不需要設置,默認會去檢查,而屬性注入並不是默認行爲。但是我們可以通過設置,讓屬性注入也成爲自動注入。
通過反射,使用PropertiesAutowired()修飾符注入屬性
builder.RegisterType<A>().PropertiesAutowired(); builder.RegisterType<B>(); using (var container = builder.Build()) { var a = container.Resolve<A>(); }
使用PropertiesAutowired也只是能指定某個類會自動進行屬性注入,沒有一鍵設置所有類型都會自動注入屬性的設置。而且還需要注意一點,設置了自動屬性注入後,也不代表所有屬性都會自動注入,只有註冊到Autofac中的類型才能自動注入。PropertiesAutowired方式會自動注入所有可以注入的屬性(在容器中已註冊的類型中尋找),但是如果只想注入指定幾個屬性,可以使用除PropertiesAutowired以外的幾種注入方式
如果預先知道屬性的名字和值,可以使用:WithProperty,此時類型B是可以不被註冊的,因爲在WithProperty方法中進行了實例化
builder.RegisterType<A>().WithProperty("_b", new B()); using (var container = builder.Build()) { var a = container.Resolve<A>(); }
lambda表達式
builder.Register(c => new A { _b = c.Resolve<B>() }); builder.RegisterType<B>(); using (var container = builder.Build()) { var a = container.Resolve<A>(); }
方法注入
使用Activator:注意,使用這種方法,類裏必須要有這個方法
class A { public B _b; public A() { } public A(B b) { this._b = b; } public void SetInject(B b) { _b = b; } }
builder.Register(c => { var _a = new A(); _a.SetInject(new B()); return _a; }); using (var container = builder.Build()) { var a = container.Resolve<A>(); }
SetInject爲A的一個方法,並且它需要一個類型爲B的參數,我們在外部通過方法的方式將B傳入,這就是方法注入
使用Activating Handler 一行代碼解決
builder.Register<A>(c => new A()).OnActivating(e => e.Instance.SetInject(new B())); using (var container = builder.Build()) { var a = container.Resolve<A>(); }