天天看點

Ioc容器-Autofac之三-三種注冊方式



簡單來說,所謂注冊元件,就是注冊類并映射為接口,然後根據接口擷取對應類,Autofac将被注冊的類稱為元件。 雖然可像上篇提到的一次性注冊程式集中所有類,但AutoFac使用最多的還是單個注冊。這種注冊共有三種方式,其中最簡單的就是用As方法,例如,ArrayList繼承了IEnumerable接口,若将其注冊到Autofac中,寫法如下所示:

ContainerBuilder builder = new ContainerBuilder();   
            builder.RegisterType<ArrayList>().As<IEnumerable>();   
            // then   
            IContainer container = builder.Build();   
            ArrayList result = (ArrayList)container.Resolve<IEnumerable>();      

有時難免碰到多個類映射到同一種接口,比如ArrayList和SortedList都繼承了IEnumerable接口,為了準确擷取想要的類型,就有了第二種方式--Named方法,可根據字元串注冊并解析相應的類。代碼如下:

builder.RegisterType<ArrayList>().Named<IEnumerable>("array");   
            builder.RegisterType<SortedList>().Named<IEnumerable>("sort");   
            // then   
            IContainer container = builder.Build();   
            ArrayList result = (ArrayList)container.ResolveNamed<IEnumerable>("array");   
            SortedList result1 = (SortedList)container.ResolveNamed<IEnumerable>("sort");      

然而相對于字元串,枚舉更易讀易用,但在Autofac中使用枚舉會有些麻煩,因為Named隻接受字元串,必須将枚舉轉換成字元串才能使用。比如,現在用ListType枚舉來代替“array”和“sort”字元串。如下所示:

public enum ListType{ Array, Sort }   
builder.RegisterType<ArrayList>().Named<IEnumerable>(ListType.Array.ToString());      

這種轉換略顯笨拙,而且讓枚舉失去原有價值。于是,為不多此一舉,第三種方式就産生了--Keyed方式,該方法可以接受任何類型作為參數。以上文中的ListType枚舉為例,代碼如下:

builder.RegisterType<ArrayList>().Keyed<IEnumerable>(ListType.Array);   
            builder.RegisterType<SortedList>().Keyed<IEnumerable>(ListType.Sort);   
            // then   
            IContainer container = builder.Build();   
            ArrayList result = (ArrayList)container.ResolveKeyed<IEnumerable>(ListType.Array);   
            SortedList result1 = (SortedList)container.ResolveKeyed<IEnumerable>(ListType.Sort);      

無論使用As、Named還是Keyed都可達到注冊目的,根據個人喜好而定。但從功能上來講,Autofac的設計者推薦第三種。

通過IIndex索引查找被Keyed辨別過的類

如果使用Keyed方法注冊類,可通過Autofac内置索引來查找指定的值,這個索引的類型是IIndex<Tkey,TValue>,以上文的枚舉為例,可通過索引完成解析,代碼如下:

IIndex<ListType, IEnumerable> allList = container.Resolve<IIndex<ListType, IEnumerable>>();   
            ArrayList result = (ArrayList)allList[ListType.Array];   
            SortedList result1 = (SortedList)allList[ListType.Sort];