天天看點

Autofac - 服務

上一篇中, 留了一個小問題,在一個接口下面, 注冊多個類, 并能正常擷取. 之前的方式是不能做到的, 在服務中, 有一種實作方式是可以的.

一、服務

1. 類型 - 描述服務的基本方法

上一篇其實使用到過這種方式, 隻是并沒有拿出來講.

builder.RegisterType<Dog>().As<IAnimal>();

//-------------------------------------------------
var animal = container.Resolve<IAnimal>();
animal.Say();      

這個方法, 就可以将IAnimal類型的服務與Dog的元件連接配接起來. 通過這個服務, 可以建立Dog的執行個體. 

按照類型的服務在自動裝配中, 也是管用的.

2. 别名

builder.RegisterType<Dog>().Named<IAnimal>("dog");
builder.RegisterType<Cat>().Named<IAnimal>("cat");
//-------------------------------------------------
var dog = container.ResolveNamed<IAnimal>("dog");
dog.Say();
Console.WriteLine();
var cat = container.ResolveNamed<IAnimal>("cat");
cat.Say();      
Autofac - 服務

從此方式來看, 是可以實作之前功能的. 在同一個接口下面, 注冊多個類, 并正常擷取他們的實體

Named方法, 本質上還是調用的As()方法

Autofac - 服務

别名的方式, 有些寬泛, 這裡我想怎麼寫都行, 沒有什麼限制(規範), 更不知道裡面有些什麼. 使用起來, 有些不是很友善.

對于這一點, autofac也是考慮到了的, 是以提供了另一種方式.

3. 鍵

首先建一個讓人能看懂的枚舉

public enum AnimalEnum
{ 
    Dog,
    Cat
}      

有了這個實體之後, 就能知道, IAnimal服務下面, 可以注冊那些類, 可以擷取到那些類的實體

builder.RegisterType<Dog>().Keyed<IAnimal>(AnimalEnum.Dog); 
builder.RegisterType<Cat>().Keyed<IAnimal>(AnimalEnum.Cat);
//-------------------------------------------------
var dog = container.ResolveKeyed<IAnimal>(AnimalEnum.Dog);
dog.Say();
Console.WriteLine();
var cat = container.ResolveKeyed<IAnimal>(AnimalEnum.Cat);
cat.Say();      
Autofac - 服務

Keyed<>()方法, 和Named<>()方法一樣, 都是調用As()方法, 隻是對值的限制有些不同.

從結果看, 與别名的方式, 是一樣的. 不過有利就有弊, 雖然能清晰看到可用的類, 但是在擴充性上就差了一些, 如果你想新增一個類進去, 就得修改AnimalEnum枚舉值. 

除了上面兩種擷取方式之外, 還有一種Index索引的擷取方式.

var iindex = container.Resolve<IIndex<string, IAnimal>>();
var cat = iindex["cat"];
cat.Say();

var index = container.Resolve<IIndex<AnimalEnum, IAnimal>>();
var dog = index[AnimalEnum.Dog];
dog.Say();      
Autofac - 服務

注冊部分, 是跟之前是一樣的, 隻是取的時候不一樣. 當不知道iindex["cat"]中, "cat"的具體值時, 這裡報錯幾率會增加不少. 是以, 推薦還是使用下面枚舉的那種

4. 周遊方式

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();
//-------------------------------------------------
var list = container.ComponentRegistry.Registrations.ToList();
var s = container.ResolveComponent(list[3], new List<Parameter>()) as Dog;
s.Say();      
Autofac - 服務

這裡我首先注冊目前運作的程式集, 然後, 通過Registrations擷取到, 所有注冊了的類型, 之後應該周遊這些類型, 找到你想要的,

Autofac - 服務

然後調用ResolveComponent方法, 去擷取執行個體. 這裡我省懶了(某人比較懶), 哈哈. 此方式不推薦使用

參考:

 Autofac 元件、服務、自動裝配 《第二篇》

 Autofac文檔