2011-05-27 42 views
0

我有兩個類實現服務中的合同,這些合同在客戶端的工廠中使用,如下所示。如何在wcf中使用注入

[ServiceContract] 
public interface MyInterface { 
    void DoSomething() 
} 


public class A : MyInterface { 
    public void DoSomething(){ 
     "Hi I'm A" 
    } 
} 

public class B : MyInterface { 
    public void DoSomething(){ 
     "Hi I'm B" 
    } 
} 

public class MyFactory <TMyInterface> { 
    void DoSomething(){ 
     TMyInterface.DoSomething() 
    } 
} 

客戶端必須保持不變。我的問題是我怎麼能選擇在服務器端使用哪種實現MyInterface的,而應使用合格的類型參數config文件中WCF

我讀其他職位,但我還不明白:(

+0

圖片中的WCF在哪裏? MyInterface是服務合同嗎?您是否試圖在客戶端或服務器上調用MyFactory .DoSomething? – carlosfigueira 2011-05-27 22:34:02

+0

MyFactory必須是來自我的客戶端的服務合約我只想致電工廠,服務負責根據他的配置來解決和使用實施 – TedTel 2011-05-27 22:50:45

+0

因此,您不想更改客戶端代碼或配置,但根據* server * config更改在服務器端調用哪個類? – carlosfigueira 2011-05-28 15:05:46

回答

1

有可能做到這一點,有幾種方法可以做到這一點

一種可能性是創建一個「路由」服務,它將包含客戶端總是與之對話的「公共」地址,該路由服務可以然後,根據某些配置,將呼叫重定向到適當的「真實」服務。

另一種方法是將通常有一個啓動這兩個服務的過程,但他們的地址是在config中定義的。如果您使用相同的綁定和相同的合同(情況如此),那麼當您想要更改將接收來自客戶端的呼叫的服務時,您可以「翻轉」服務地址。例如,該配置將請求發送到端點「http:// machine-name:8000/Service」到服務A.請注意,由於您爲兩個服務定義了服務主機,實際上您需要有一個基地址服務B - 在這種情況下,我使用命名管道,不能通過不同的機器訪問。

<system.serviceModel> 
    <services> 
     <service name="A"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://machine-name:8000/Service"/> 
      </baseAddresses> 
     </host> 
     <endpoint address="" binding="basicHttpBinding" contract="MyInterface" /> 
     </service> 
     <service name="B"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="net.pipe://localhost/ServiceBackup"/> 
      </baseAddresses> 
     </host> 
     <endpoint address="" binding="netNamedPipeBinding" contract="MyInterface" /> 
     </service> 
    </services> 
    </system.serviceModel> 

當你想改變B的地址時,你會交換地址。

<system.serviceModel> 
    <services> 
     <service name="A"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="net.pipe://localhost/ServiceBackup"/> 
      </baseAddresses> 
     </host> 
     <endpoint address="" binding="netNamedPipeBinding" contract="MyInterface" /> 
     </service> 
     <service name="B"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://machine-name:8000/Service"/> 
      </baseAddresses> 
     </host> 
     <endpoint address="" binding="basicHttpBinding" contract="MyInterface" /> 
     </service> 
    </services> 
    </system.serviceModel> 

託管程序是這樣的:

public static void HostServices() 
{ 
    ServiceHost hostA = new ServiceHost(typeof(A)); 
    ServiceHost hostB = new ServiceHost(typeof(B)); 
    hostA.Open(); 
    hostB.Open(); 
    Console.WriteLine("Press ENTER to close"); 
    Console.ReadLine(); 
    hostA.Close(); 
    hostB.Close(); 
} 

現在,如果你的服務在IIS(主機服務商)託管,那麼它是一個有點困難。由於「正常」激活需要將.svc文件作爲端點地址的一部分,並且每個.svc文件都與一個類關聯,所以A的地址應該類似於http://machine-name/services/a.svc,而B的地址應該類似於http://machine-name/services/b.svc 。所以在這種情況下你需要做的是創建一個自定義的ServiceHostFactory,並使用ASP.NET Routes集成爲你的服務創建一個.svc-less的URL。然後你會使用類似於前面例子的東西來決定哪個服務將被激活。

+0

我很欣賞你的答案,我會嘗試實現你的想法並在稍後發佈我的結果,但是對我來說很快就會有一個很好的解決方案謝謝! :) – TedTel 2011-05-29 17:48:36