2013-05-11 12 views
13

Ist es möglich, mehrere Serviceverträge in einem WCF-Dienst zu hosten? Wenn das so ist, wie? Ich habe gegoogelt und einige Beiträge sagen, dass Sie es tun können (aber nicht wie) und andere haben gesagt, dass es einfach nicht möglich ist.Host mehrere Verträge in einem WCF-Dienst

Wenn ich den Server laufen, bekomme ich diesen Fehler:

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

Das ist mein Server-Code ist:

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(); 
    } 

Und dies ist der Client-Code:

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()); 
    } 

Mein Ziel ist es zu lassen Der Client ruft Foo (oder Bar) an und sieht nur die verfügbaren Methoden. In meiner realen Anwendung habe ich etwa 10 Domäneneinheiten mit jeweils ungefähr vier Operationen. Ich versuche, keine Schnittstelle mit 40 Methoden zu haben. Und ich möchte dazu nicht 10 verschiedene WCF-Dienste hosten müssen.

+3

Der einzige Weg, dies zu tun ist ** eine Service-Implementierungsklasse haben **, die implementiert ** ** beide Schnittstellen in Frage . Hast du das? Also müssten Sie 'öffentliche Klasse FooService haben: IFooService, IBarService {....}' –

+1

http://Stackoverflow.com/a/334554/352101 – Bolu

+0

@marc_s Ich habe das nicht, aber ich könnte als ich Besitze den gesamten Code. In meinem obigen Beispiel, sagst du, dass der Server-Code so funktionieren sollte wie er ist, wenn FooService beide Schnittstellen implementiert? –

Antwort

21

Wie marc_s darauf hinwies, war die Antwort, eine Service-Implementierungsklasse zu haben, die beide Schnittstellen implementiert. Unten ist der vollständige Arbeitscode.

Server:

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(); 
    } 

Auftraggeber:

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(); 
    } 

Foo Vertrag:

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

    [OperationContract] 
    string FooMethod2(); 
} 

Bar Vertrag:

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

    [OperationContract] 
    string BarMethod2(); 
} 

Foo Service:

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

Ich mag es wirklich, dass Sie Ihren Endergebniscode gepostet haben - das hilft anderen, mich eingeschlossen. Ich sehe Kommentare wie ich den endgültigen Code posten werde; und doch tun die Leute das einfach nicht und ich haue mir den Kopf! ++ – Stix

+0

Guter Code, aber wenn ich in WCF bin gehostet auf IIS, wo lege ich das Zeug, das in Main geht? – Rhyous

+0

Es wäre in dem Bereich Ihres WCF-Diensts, der Dinge initialisiert, wenn der Dienst gestartet wird. Wo legen Sie derzeit die Bindungen und Endpunkte fest? Da würde dieser Code gehen. –

Verwandte Themen