2009-09-17 156 views
6

我們使用WCF在客戶端和服務器應用程序之間進行通信。客戶端應用程序有許多功能需要與服務器通信 - 我們選擇在多個類中實現此功能(分離責任)WCF服務返回另一個服務(服務工廠?)

當時,我們正在爲每個對象創建新的WCF端點和服務合同 - 開發票,會計,內容管理等。這會在客戶端和服務器上導致大量的端點配置(當進入測試和生產平臺時可能存在錯誤配置問題)。

我想知道我是否可以定義一個可以提供多個服務聯繫實現的單個WCF端點。然後我們的配置文件將包含單個端點(到服務工廠),並且我可以通過指定我感興趣的服務的接口來請求不同的服務。

例如,

using (IServiceClientFactory serviceClientFactory = new RealProxyServiceClientFactory()) 
      { 
       // This is normal WCF proxy object creation. 
       IServiceFactory serviceFactory = serviceClientFactory.CreateInstance<IServiceFactory>(""); 

       // This is what we would like to do 
       IInvoiceService invoiceService = serviceFactory.getService(typeof(IInvoiceService)); 

       invoiceService.executeOperation(data); 
      } 

線索是每客戶端/服務器對的單個端點的配置,而不是每個服務接觸的端點配置我想作用。

這可能嗎?

回答

1

我懷疑這會起作用。 Xml序列化可能是這裏最大的問題。

另外我不認爲你真的需要它。如果我在你的鞋子裏,我會盡量抽象與服務的溝通。基本上你總是會發送一個「消息」給服務,它有一個「目標」是你想要訪問的類之一。該服務將始終以「響應」回覆,其中內容將由「消息」發送到的類填充。

另一種方法是將所有這些消息通過一個服務路由到服務,該服務將請求轉發給相應的服務。這樣可以保持可擴展性,但它仍然有很大的配置負擔。

HTH。

+0

謝謝你的回覆。序列化服務不是解決方案,服務上的方法需要在服務器上處理。參數需要是可序列化的,但方法本身必須在服務器上執行。我用一個SessionMode找到了一個關於ServiceContracts的文檔,現在我正在嘗試。 – Thies 2009-09-17 08:32:58

+0

我從來沒有建議序列化服務。 Xml序列化是WCF的工作原理。它負責把你的對象和翻譯成Xml和其他方式。 我的答覆的重點是向您解釋,包裝您的服務請求和回覆可能很好地解決了您的問題。 – 2009-09-18 08:08:55

3

我並不十分清楚你想要做什麼,但是如果你只是想能夠在一個服務類中實現同一個地址上的不同契約,這是完全可能的。要共享端點地址,您必須確保您爲每個服務端點使用相同的綁定實例。

這裏是一個定義了3項合同,1個服務類,它實現所有的人,並在完全相同的地址與3個合同端點的ServiceHost一個完整的示例:

using System; 
using System.ServiceModel; 

[ServiceContract] 
interface IContractA 
{ 
    [OperationContract] 
    void A(); 
} 

[ServiceContract] 
interface IContractB 
{ 
    [OperationContract] 
    void B(); 
} 

[ServiceContract] 
interface IContractC 
{ 
    [OperationContract] 
    void C(); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
class Service : IContractA, IContractB, IContractC 
{ 
    public Service() 
    { 
    } 

    public void A() 
    { 
     Console.WriteLine("A"); 
    } 

    public void B() 
    { 
     Console.WriteLine("B"); 
    } 

    public void C() 
    { 
     Console.WriteLine("C"); 
    } 
} 

class Program 
{ 
    public static void Main(string[] args) 
    { 
     Uri address = new Uri("net.pipe://localhost/Service/"); 
     ServiceHost host = new ServiceHost(new Service(), address); 
     NetNamedPipeBinding binding = new NetNamedPipeBinding(); 
     host.AddServiceEndpoint(typeof(IContractA), binding, string.Empty); 
     host.AddServiceEndpoint(typeof(IContractB), binding, string.Empty); 
     host.AddServiceEndpoint(typeof(IContractC), binding, string.Empty); 
     host.Open(); 

     IContractA proxyA = ChannelFactory<IContractA>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address)); 
     proxyA.A(); 
     ((IClientChannel)proxyA).Close(); 

     IContractB proxyB = ChannelFactory<IContractB>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address)); 
     proxyB.B(); 
     ((IClientChannel)proxyB).Close(); 

     IContractC proxyC = ChannelFactory<IContractC>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address)); 
     proxyC.C(); 
     ((IClientChannel)proxyC).Close(); 

     host.Close(); 
    } 
} 
+0

謝謝bobby,在你知道解決方案之前,定義一個問題並不總是很容易;)。如你所述;我有興趣在同一個地址上託管多份合同 - 但最好還是在不同類別中實施服務。使用你的建議,我會有一個單獨的「怪獸」類,通過在正確的非WCF服務上調用呼叫來實現所有服務 - 這是我想避免的。 – Thies 2009-09-17 08:49:38

+0

聽起來很難實現你想要的一切。如果你希望客戶端有一個很好的類型化契約,但你實際上並不希望你的服務類實現它們,那麼你可能會寫很多奇怪的通用消息處理代碼,並重寫WCF元數據行爲, WSDL仍然可以生成。 – bobbymcr 2009-09-18 05:40:58

0

聽起來像是你想保留你的單獨服務,但有某種巴士,路線是經過。也許MSMQ,那麼你可以有一個服務,每個消息彈出它到一個特定的隊列,然後一個專用的服務可以讀取那個特定的隊列。

儘管承認不是一個基於WCF的解決方案。

由多個類實現的單個接口(讀爲ServiceContract)的概念將無法工作。所以你需要一個「怪物」服務來實現所有的服務,並且路由到正確的服務。門面模式涌入腦海。