2010-09-21 92 views
2

我有一個接口,例如ISomeServiceISomeService提供了一項通用服務,但實現可能有所不同。因此,他們將有不同的依賴關係。在Autofac中實現通用服務工廠或提供商

考慮:現在

interface ISomeService 
{ 
    void DoSomething(); 
} 

class SomeServiceA : ISomeService 
{ 
    public SomeServiceA(DependencyOne one, DependencyTwo two) 
    { 
    } 


    public void DoSomething() 
    { 
    } 
} 

class SomeServiceB : ISomeService 
{ 
    public SomeServiceB(DependencyThree three) 
    { 
    } 

    public void DoSomething() 
    { 
    } 
} 

,但現實是我不能只是添加一個依賴於ISomeService到我的控制器,並用它來完成。我需要根據用戶告訴我的內容來選擇IService的實現,並且我可能必須創建它們所選服務的多個副本。

也許我有一個類,讓我來解決ISomeService我需要的情況下,按類型:

class SomeServiceProvider 
{ 
    public T Get<T>() 
     where T : ISomeService 
    { 
      // uh oh, this is starting to have a bad smell... do I call the container? that's no good 
    } 

} 

,所以我可以

class SomeController 
{ 
    SomeServiceProvider ServiceProvider { get; set; } 

    public SomeController(ServiceProvider provider) 
    { ServiceProvider = provider; } 

    public void SomeAction(string serviceName) 
    { 
      ISomeService someService; 
      if (serviceName.Equals('SomeServiceA')) someService = ServiceProvider.Get<SomeServiceA>(); 
      else someService = ServiceProvider.Get<SomeServiceB>(); 
      someService.DoSomething(); 
    } 

} 

看來,Autofac的委託工廠在這裏不合適,我不知道該怎麼做(除了使用服務定位器)。任何建議?

回答

2

這是你所需要的? Service types, names and keys

可以使用服務名稱進一步標識服務。使用這種技術,Named()註冊方法替代As()。

builder.Register<OnlineState>().Named<IDeviceState>("online"); 

檢索名爲的服務, ResolveNamed()方法:

var r = container.ResolveNamed<IDeviceState>("online"); 
+0

我認爲部分**解決您的鏈接索引**會做我想要什麼,但是我必須編寫一個需要引用Autofac本身的組件,這有點尷尬。但是,我想我可以解決這個問題。謝謝! – HackedByChinese 2010-09-22 06:34:12

+1

我會建議創建一個使用IIndex並實現ISomethingFactory的SomethingFactory,然後您可以在控制器中使用它 - 兩全其美! :)像IIndex這樣的類型最好保存在應用程序的基礎結構部分 - 與IoC容器交互的地方 - 而不是常規的應用程序組件。祝您好運!缺口 – 2010-09-22 07:46:34