2011-03-02 95 views
12

不像ASMX實施WCF需要你來實現它的界面。我不太明白這個設計背後的原因。接口爲2類之間的合同......有了這樣說,你經常有satisfry相同的接口,但正在實施不同的2 WCF服務?爲什麼.NET WCF服務所需要的接口

另一個意見,在MSDN強烈建議要做到這一點:

MyService service = new MyService(); 

    try { 

     service.DoWork(); 

    } 
    catch(Exception) {} 
    finally { 
     service.Close(); 
    } 

所以我們說如果我要使用它是這樣的接口,插入我的服務:

public MyComponent : IDisposable 
    { 

     readonly IMyService service = null; 

     public MyComponent(IMyService service) { 

      this.service = service; 

     } 

     public DoWork() 
     { 
      //some additional code. 
      this.service.DoWork(); 

     } 

     public void Dispose() 
     { 
      //The Interface does not have the Close method, 
      //So doing this defeats the whole purpose of polymorphysm 
      (this.service as MyService).Close(); //Silly. 
     } 
    } 

你怎麼拿與WCF的接口的優點?

回答

24

沒有,WCF 並不需要你有一個接口,並實現它。

這只是普遍的最佳實踐這麼做 - 但你不知道,如果你不想。

如果你願意,你可以把你的[ServiceContract]上有很多[OperationContract]服務方法的具體類 - 有沒有這樣做阻止你。

但同樣:它通常被接受和傳播的最佳做法是使用一個接口來將實際契約分離爲一個接口(因此您可以例如將其模擬以進行測試等)。

+0

其實,至少有一件事阻止了你:繼承。您可以在從多個接口繼承的接口上應用[ServiceContract],同時還應用[ServiceContract],使服務合約變爲模塊化。如果你將一個[ServiceContract]應用到一個類中,它既不能繼承也不能繼承 - 你被這個類自己定義的任何契約所困住。 – Suncat2000

6

可以不使用的接口創建一個WCF服務:

[ServiceContract] 
public class TheService 
{ 
    // more stuff here 
} 

這就是說,建議將它們分開。將合同與實施分離可以帶來一些不同的優點:

  • 您可以將接口放入單獨的部件中。該組件可以通過任何一段代碼,需要了解該接口可以使用,但不一定對實施。我有時使用它來構造一種服務網關,將通信包裝到服務中。
  • 你可以有一個類實現多個接口。這意味着您可以使用WCF端點中的不同接口以不同方式公開相同的實現類。

還有其他原因,但這些立即浮現在腦海中。

9

其實,即使MSDN不時承認時間是接口的形式可能並不總是「做正確的事」:

http://msdn.microsoft.com/en-us/library/ms733070.aspx

「通過應用ServiceContractAttribute的創建服務的優勢, OperationContractAttribute直接到類和類上的方法,分別是速度和簡單「。在dotnet接口中使用

1

來描述行爲。 WCF,Web服務和遠程處理這一切技術都使用RPC(遠程過程調用)行爲。RPC中的 必須有一些通用客戶端和服務器共享的綁定。

如果您使用的是類而不是接口,那麼您也可以將生成的dll文件共享給客戶端。因此你的邏輯進入客戶端,這不是很好的做法。這就是我們使用接口的原因。

1

如果您創建的服務沒有接口,那麼您將失去在代碼中動態創建通道的能力。然後,您可以訪問該服務的唯一方法是添加服務引用。

嘗試使用默認的VS 2015 WCF服務模板;用ServiceContractOperationContract屬性標記服務等級。接口實現被刪除(無接口實現)。

[ServiceContract] 
public class Service1 
{ 
    [OperationContract] 
    public string GetData(int value) 
    { 
     return string.Format("You entered: {0}", value); 
    } 

    [OperationContract] 
    public CompositeType GetDataUsingDataContract(CompositeType composite) 
    { 
     if (composite == null) 
     { 
      throw new ArgumentNullException("composite"); 
     } 
     if (composite.BoolValue) 
     { 
      composite.StringValue += "Suffix"; 
     } 
     return composite; 
    } 
} 

有了這個變化,我們不能創建代理渠道,我試着用下面的一段代碼。

BasicHttpBinding myBinding = new BasicHttpBinding(); 
    EndpointAddress myEndpoint = new  EndpointAddress("http://localhost:59420/Service1.svc"); 
    // InvalidOperationException is thrown as below line 
    // Error message "The type argument passed to the generic ChannelFactory class must be an interface type" 
    ChannelFactory<Service1> myChannelFactory = new ChannelFactory<Service1>(myBinding, myEndpoint); 
    // Create a channel. 
    Service1 wcfClient1 = myChannelFactory.CreateChannel(); 
    Console.WriteLine(wcfClient1.GetData(1)); 
    Console.ReadKey(); 

如果我們使用和實現界面如下

public class Service1 : IService1 

然後下面的代碼運行沒有任何問題。現在請在創建ChannelFactory對象時將Service1替換爲IService1接口。

ChannelFactory<IService1> myChannelFactory = new ChannelFactory<IService1>(myBinding, myEndpoint); 

這是最重要的方面,如果您的客戶端使用的ChannelFactory,而不是服務引用來訪問服務。

+0

一些文章可以走很長一段路.....嚴重。這是不可讀的 –