2013-05-11 100 views
13

是否有可能在一個WCF服務中託管多個服務合同?如果是這樣,怎麼樣?我一直在Google上搜索,有些帖子說你可以做(​​但不是如何),其他人說這是不可能的。在一個WCF服務中託管多個合同

當我運行服務器,我得到這個錯誤:

The contract name 'ConsoleAppWcfCommon.IBarService' could not be found in the list of contracts implemented by the service 'ConsoleAppWcfServer.FooService'.

這是我的服務器代碼:

static void Main(string[] args) 
    { 
     string serviceAddress = "net.tcp://localhost:8088/FooBarService"; 

     // I'm stuck here as I have to pick *one* service 
     ServiceHost selfServiceHost = new ServiceHost(typeof(FooService));    

     // I can add both endpoints here, but this is what gives me the error. 
     selfServiceHost.AddServiceEndpoint(typeof(IFooService), new NetTcpBinding(), serviceAddress); 
     selfServiceHost.AddServiceEndpoint(typeof(IBarService), new NetTcpBinding(), serviceAddress); 

     selfServiceHost.Open(); 
     Console.ReadLine(); 
     selfServiceHost.Close(); 
    } 

這是客戶端代碼:

static void Main(string[] args) 
    { 
     NetTcpBinding netTcpBinding = new NetTcpBinding(); 

     EndpointAddress endpointAddress = new EndpointAddress("net.tcp://localhost:8088/FooBarService"); 

     // Call IFooService 
     var channelFactoryFoo = new ChannelFactory<IFooService>(netTcpBinding, endpointAddress); 
     IFooService channelFoo = channelFactoryFoo.CreateChannel(); 
     Debug.WriteLine(channelFoo.FooMethod1()); 

     // Call IBarService 
     var channelFactoryBar = new ChannelFactory<IBarService>(netTcpBinding, endpointAddress); 
     IBarService channelBar = channelFactoryBar.CreateChannel(); 
     Debug.WriteLine(channelBar.BarMethod1()); 
    } 

我的目標是讓客戶打電話給Foo(或Bar),只看到每個方法都可用。在我的真實應用程序中,我有大約10個域實體,每個域都有四個操作。我試圖不使用其中的40個方法的一個接口。我不想主辦10個不同的WCF服務來做到這一點。

+3

做到這一點的唯一方法是有一個**服務實現類**實現** **都在質疑接口。你有嗎?所以你需要有'公共類FooService:IFooService,IBarService {...}' – 2013-05-11 21:02:09

+1

http://stackoverflow.com/a/334554/352101 – Bolu 2013-05-11 21:03:41

+0

@marc_s我沒有,但我可以像我一樣擁有所有的代碼。在我上面的例子中,你是否說如果FooService實現兩個接口,服務器代碼應該按原樣工作? – 2013-05-11 21:06:16

回答

21

正如marc_s指出的,答案是有一個服務實現類實現兩個接口。以下是完整的工作代碼。

服務器:

static void Main(string[] args) 
    { 
     string serviceAddress = "net.tcp://localhost:8088/FooBarService"; 

     ServiceHost selfServiceHost = new ServiceHost(typeof(FooService));    

     // The endpoints need to share this binding. 
     var binding = new NetTcpBinding(); 

     selfServiceHost.AddServiceEndpoint(typeof(IFooService), binding, serviceAddress); 
     selfServiceHost.AddServiceEndpoint(typeof(IBarService), binding, serviceAddress); 

     selfServiceHost.Open(); 

     Console.WriteLine("The service is ready."); 
     Console.WriteLine("Press any key to terminate service."); 
     Console.WriteLine(); 
     Console.ReadKey(); 

     selfServiceHost.Close(); 
    } 

客戶:

static void Main(string[] args) 
    { 
     NetTcpBinding netTcpBinding = new NetTcpBinding(); 

     EndpointAddress endpointAddress = new EndpointAddress("net.tcp://localhost:8088/FooBarService"); 

     // Call IFooService 
     var channelFactoryFoo = new ChannelFactory<IFooService>(netTcpBinding, endpointAddress); 
     IFooService channelFoo = channelFactoryFoo.CreateChannel(); 
     Console.WriteLine(channelFoo.FooMethod1()); 

     // Call IBarService 
     var channelFactoryBar = new ChannelFactory<IBarService>(netTcpBinding, endpointAddress); 
     IBarService channelBar = channelFactoryBar.CreateChannel(); 
     Console.WriteLine(channelBar.BarMethod1()); 

     Console.ReadKey(); 
    } 

美孚合同:

[ServiceContract] 
public interface IFooService 
{ 
    [OperationContract] 
    string FooMethod1(); 

    [OperationContract] 
    string FooMethod2(); 
} 

酒吧合同:

[ServiceContract] 
public interface IBarService 
{ 
    [OperationContract] 
    string BarMethod1(); 

    [OperationContract] 
    string BarMethod2(); 
} 

富服務:

public class FooService : IFooService, IBarService 
{ 
    public string FooMethod1() 
    { 
     return "FooMethod1"; 
    } 

    public string FooMethod2() 
    { 
     return "FooMethod2"; 
    } 

    public string BarMethod1() 
    { 
     return "BarMethod1"; 
    } 

    public string BarMethod2() 
    { 
     return "BarMethod2"; 
    } 
} 
+1

我非常喜歡您發佈了最終結果代碼 - 這確實有助於其他人,包括我在內。我看到像我將發佈最終代碼的評論;然而人們卻不這麼做,我只能狠狠敲我的頭! ++ – Stix 2016-02-05 16:47:16

+0

不錯的代碼,但是如果我在WCF託管在IIS上,我應該在哪裏放置Main中的東西? – Rhyous 2016-06-15 16:27:31

+0

當您的WCF服務啓動時,它將會初始化事物。你目前在哪裏設置綁定和端點?這就是代碼的用處。 – 2016-06-15 17:14:06