2012-08-13 83 views
1

Autofac是否支持通過名稱解析服務?或者我必須總是指定一種服務類型?Autofac僅按名稱解析?

我想做的事:

container.ResolveNamed("Plugin"); // or container.TryResolvedNamed("Plugin", out instance); 

container.ResolvedNamed<ISomeInterface>("Plugin"); // etc 

其中 「插件」 是註冊名稱/鍵,不是一個類型。

謝謝!

+0

這沒有意義,除非你想讓它返回'object'。 – SLaks 2012-08-13 22:03:05

+0

其實,這很好,因爲我在Xaml綁定環境中。實際上,它是與Caliburn相關的一個小集成部分,如果這有助於提供更大的上下文。 Caliburn的Bind類有一個方法,試圖通過名稱來解析所選的IoC容器,而不是類型。 – robcecil 2012-08-13 22:09:29

+0

具體而言:Bind.ModelChanged(...)是有問題的方法。它嘗試通過使用以下行的IoC容器進行檢索: target = IoC.GetInstance(null,containerKey); 因此,Caliburn假設提供的IoC風格將支持以這種方式進行檢索。不確定Autofac是否能夠以這種方式工作。 (IoC只是Caliburn源代碼中的一個門面類,它抽象出任何容器的細節......) – robcecil 2012-08-13 22:14:22

回答

0

這是我如何解決了這個問題:

private Type GetTypeForName(string key) 
    { 
     return (
      from reg in Container.ComponentRegistry.Registrations 
      from service in reg.Target.Services.OfType<KeyedService>() 
      .Where(service => service.ServiceKey.ToString() == key) 
      select service.ServiceType).FirstOrDefault(); 
    } 

顯然,不是一個完美的解決方案,因爲它是可以想象可能有多個註冊使用相同的密鑰。

1

您必須指定一個Type在Autofac解析服務,或者通過泛型參數或Type參數。兩種選擇:

  1. 註冊所有相關服務和附加.Named<object>("service name")
  2. 維護您自己的Dictionary<string, Type>,以便在通過Autofac解析之前自己查看類型。

我可能會去選擇1,假設你已經控制了所有的註冊碼。

0

如果您維護服務之間的密鑰的唯一性,這個擴展方法將幫助:

private static object ResolveSingleOrDefaultByName(this IComponentContext cc, string name) 
    { 
     var reg = cc.ComponentRegistry.Registrations.SingleOrDefault(r => 
      r.Services.OfType<KeyedService>().Any(s => name.Equals(s.ServiceKey))); 
     return reg == null ? null : cc.ResolveComponent(reg, Enumerable.Empty<Parameter>()); 
    } 

它會返回null,如果沒有找到關鍵。