2012-02-02 28 views

回答

8

簡短的回答是:不,開箱即用,您必須擁有該類型。

應該有,因爲,從技術上講,你可以用不同類型的註冊兩個不同的命名服務類型:無類型

builder.RegisterInstance(someObject).Named<IFoo>("name-here"); 
builder.RegisterInstance(someOtherObject).Named<IBar>("name-here"); 

,你會排序的「得到你會得到什麼。」如果你明白我的意思。這是不可預測的。

有沒有官方支持的方式來得到你要找的東西,但你也許可以破解自己的解決方案。事情是這樣的:

public static object ResolveUntypedNamed(
    this IComponentContext context, 
    string serviceName) 
{ 
    var component = context.ComponentRegistry.Registrations 
    .Where(r => r.Services.OfType<KeyedService>() 
     .Any(s => s.ServiceKey.Equals(serviceName))) 
    .FirstOrDefault(); 
    return context.ResolveComponent(component, Enumerable.Empty<Parameter>()); 
} 

不過,我真的不能推薦這樣做。使Autofac變得更加靈活的事情之一就是擁有可以做一些有趣的後期事情的「註冊來源」。當您以「正確的方式」解決服務時,需要進行一些初始化和掃描,以確保需要動態註冊的所有內容實際上都得到了動態註冊。當您訪問組件註冊表中的註冊列表時,它將列出的所有內容,其中可能不包含您正在查找的指定服務......在這種情況下,您將無法解析否則你可能不會。

如果你沒有在你的應用中使用任何動態註冊的東西,你可能是安全的。要知道,你有點像這樣的事情,你可能得不到預期的結果。如果/當奇怪的事情開始發生,你已被警告

如果您想以正確的方式註冊和解決untyped服務,您可能需要實現您自己的Autofac.Core.Service。鍵控/命名註冊是Autofac.Core.KeyedService,但它們始終具有關聯的類型;你的自定義的一個將不需要輸入。然後,您就需要實現對ContainerBuilder例如,你可以這樣做你自己註冊的擴展:

builder.RegisterUntypedNamed(someObject, "name-here"); 

...然後你還需要會在IComponentContext相應的擴展,以便解決您的服務類型,以便你可以做正確的:

container.ResolveUntypedNamed("name-here"); 

...同時還參加了所有的後期綁定註冊/掃描的東西,那張幕後。

+0

非常全面的答覆感謝。我要問的原因是因爲我使用Caliburn Micro的Bind.Model依賴項屬性。 Caliburn使用提供給該屬性的值作爲解決DI容器中的ViewModel的鍵。類型不會傳遞。我所做的就是設置Bind.Model = <全限定名>,然後設置Type.GetType(完全限定名)。隨着類型,我可以去Autofac。 – 2012-02-02 22:49:28

相關問題