依賴注入容器Autofac的詳解[轉]

來源:互聯網
上載者:User

標籤:style   blog   http   color   io   os   使用   ar   檔案   

依賴注入容器Autofac的詳解發表於 2011 年 09 月 22 日 由 renfengbin 分享到:GMAIL郵箱         Hotmail郵箱 delicious digg

Autofac和其他容器的不同之處是它和C#語言的結合非常緊密,在使用過程中對你的應用的侵入性幾乎為零,更容易與第三方的組件整合,並且開源,Autofac的主要特性如下:

1,靈活的組件執行個體化:Autofac支援自動裝配,給定的組件類型Autofac自動選擇使用建構函式注入或者屬性注入,Autofac還可以基於lambda運算式建立執行個體,這使得容器非常靈活,很容易和其他的組件整合。 2,資源管理的可視性:基於依賴注入容器構建的應用程式的動態性,意味著什麼時候應該處理那些資源有點困難。Autofac通過容器來跟蹤組件的資源管理。對於不需要清理的對象,例如Console.Out,我們調用ExternallyOwned()方法告訴容器不用清理。細粒度的組件生命週期管理:應用程式中通常可以存在一個應用程式範圍的容器執行個體,在應用程式中還存在大量的一個請求的範圍的對象,例如一個HTTP請求,一個IIS工作者線程或者使用者的會話結束時結束。通過嵌套的容器執行個體和對象的範圍使得資源的可視化。 3,Autofac的設計上非常務實,這方面更多是為我們這些容器的使用者考慮: ●組件侵入性為零:組件不需要去引用Autofac。 ●靈活的模組化系統:通過模組化組織你的程式,應用程式不用糾纏於複雜的XML配置系統或者是配置參數。 ●自動裝配:可以是用lambda運算式註冊你的組件,autofac會根據需要選擇建構函式或者屬性注入 ●XML設定檔的支援:XML設定檔過度使用時很醜陋,但是在發布的時候通常非常有用

Autofac的簡單使用,並加入了Repository模式.

定義兩個簡單實體類:
public class Persion{    public string Name { get; set; }    public int Age { get; set; }}public class Custom{    public string CustomName { get; set; }    public int CustomID { get; set; }}

 

定義泛型資料庫提供者:
public interface Idal<T> where T:class{    void Insert(T entity);    void Update(T entity);    void Delete(T entity);}

 

泛型資料庫提供者的泛型實現:
public class Dal<T>:Idal<T> where T : class{    #region Idal<T> Members    public void Insert(T entity)    {        HttpContext.Current.Response.Write("您添加了一個:"           +entity.GetType().FullName);    }    public void Update(T entity)    {        HttpContext.Current.Response.Write("您更新一個:"             +entity.GetType().FullName);    }    public void Delete(T entity)    {        HttpContext.Current.Response.Write("您刪除了一個:"              +entity.GetType().FullName);    }    #endregion}

 

使用Repository模式實現訪問。

//Repository的泛型介面:public interface IRepository<T> where T:class{    void Insert(T entity);    void Update(T entity);    void Delete(T entity);} //Repository泛型介面的泛型實現:public class Repository<T>:IRepository<T> where T:class{    private Idal<T> _dal;    public Repository(Idal<T> dal)    {        _dal = dal;    }    #region IRepository<T> Members    public void Insert(T entity)    {        _dal.Insert(entity);    }    public void Update(T entity)    {        _dal.Update(entity);    }    public void Delete(T entity)    {        _dal.Delete(entity);    }    #endregion}

 

IDependency的依賴介面,不需要任何方法體,所有的業務對象都實現該介面
public interface IDependency{}

 

實現IDependency介面的CustomBll類,通過Repository模式儲存資料。
public class CustomBll:IDependency{    private readonly IRepository<Custom> _repository;    public CustomBll(IRepository<Custom> repository)    {        _repository = repository;    }    public void Insert(Custom c)    {        _repository.Insert(c);    }    public void Update(Custom c)    {        _repository.Update(c);    }    public void Delete(Custom c)    {        _repository.Delete(c);    }}

 

實現IDependency介面的PersionBll類,通過Repository模式儲存資料。
public class PersionBll:IDependency{    private readonly IRepository<Persion> _repository;    public PersionBll(IRepository<Persion> repository)    {        _repository = repository;    }    public void Insert(Persion p)    {        _repository.Insert(p);    }    public void Update(Persion p)    {        _repository.Update(p);    }    public void Delete(Persion p)    {        _repository.Delete(p);    }}

 

下面編寫組件執行個體化測試

var builder = new ContainerBuilder();builder.RegisterGeneric(typeof(Dal<>)).As(typeof(Idal<>))    .InstancePerDependency();builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>))    .InstancePerDependency();builder.Register(c=>new PersionBll((IRepository<Persion>)    c.Resolve(typeof(IRepository<Persion>))));builder.Register(c => new CustomBll((IRepository<Custom>)    c.Resolve(typeof(IRepository<Custom>))));//var container = builder.Build()教程裡都是使用這行代碼,//我本地測試需要加入ContainerBuildOptions枚舉選項。using (var container = builder.Build(ContainerBuildOptions.None))  {    // var repository= container.Resolve(typeof(IRepository<Persion>),new TypedParameter());    // IRepository<Persion> _repository = repository as Repository<Persion>;    // var m = new PersionBll(_repository);    Persion p = new Persion();    p.Name = "小人";    p.Age = 27;    var m = container.Resolve<PersionBll>();    m.Insert(p);    Custom c = new Custom();    c.CustomName = "小小";    c.CustomID = 10;    var cc = container.Resolve<CustomBll>();    cc.Update(c);}

這裡通過ContainerBuilder方法RegisterGeneric對泛型類進行註冊(當然也可以通過ContainerBuilder方法RegisterType對不是泛型的類進行註冊),當註冊的類型在相應得到的容器中可以Resolve你的類執行個體。 builder.RegisterGeneric(typeof(Dal<>)).As(typeof(Idal<>)).InstancePerDependency();通過AS可以讓類中通過建構函式依賴注入類型相應的介面。(當然也可以使用builder.RegisterType<類>().As<介面>();來註冊不是泛型的類 ) Build()方法產生一個對應的Container執行個體,這樣,就可以通過Resolve解析到註冊的類型執行個體。

註:如果要獲得某個泛型的執行個體,需要將泛型T代表的類傳進去。如上c.Resolve(typeof(IRepository<Persion>))返回的是Object,需要轉換為響應的介面。

當然可以使用autofac的新特性RegisterAssemblyTypes,從一個程式集的註冊類型設定根據使用者指定的規則,例子如下:

var builder = new ContainerBuilder();builder.RegisterGeneric(typeof(Dal<>)).As(typeof(Idal<>)).InstancePerDependency();builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerDependency();//上面的那些類如果在單獨的工程裡,如產生的程式集為AutofacUnitTest,就可以使用//Assembly.Load("AutofacUnitTest")獲得響應的程式集。如果所有的檔案在一個控制台程式裡,//可以通過Assembly.GetExecutingAssembly(); 直接獲得相應的程式集。Assembly dataAccess = Assembly.Load("AutofacUnitTest"); builder.RegisterAssemblyTypes(dataAccess)        .Where(t => typeof(IDependency).IsAssignableFrom(t) && t.Name.EndsWith("Bll"));//RegisterAssemblyTypes方法將實現IDependency介面並已Bll結尾的類都註冊了,文法非常的簡單。

 

此條目發表在 開源 分類目錄。將固定連結加入收藏夾。

依賴注入容器Autofac的詳解[轉]

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.