2013-05-11 17 views
13

Czy możliwe jest hostowanie wielu umów serwisowych w jednej usłudze WCF? Jeśli tak to jak? Odwiedziłem go, a niektóre posty mówią, że możesz to zrobić (ale nie jak), a inni powiedzieli, że to niemożliwe.Obsługa wielu umów w jednej usłudze WCF

Kiedy uruchomić serwer, otrzymuję ten błąd:

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

To jest mój kod serwera:

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

I to jest kod klienta:

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

Moim celem jest pozwolić klient nawiązuje połączenie z Foo (lub Bar) i widzi tylko metody dostępne dla każdego. W mojej prawdziwej aplikacji mam około 10 jednostek domenowych z około czterema operacjami na każdej z nich. Próbuję nie mieć jednego interfejsu z 40 metodami w nim. I nie chcę mieć do obsługi 10 różnych usług WCF, aby to zrobić.

+3

Jedynym sposobem, aby to zrobić, to mieć ** klasy wykonania jednej usługi, który implementuje ** ** ** oba interfejsy w pytaniu . Masz to? Więc musisz mieć 'public class FooService: IFooService, IBarService {....}' –

+1

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

+0

@ marc_s Nie mam tego, ale mogłem, tak jak ja posiadać cały kod. W powyższym przykładzie mówisz, że kod serwera powinien działać tak jak jest, jeśli FooService implementuje oba interfejsy? –

Odpowiedz

21

Jak zaznaczył marc_s, odpowiedzią była jedna klasa implementacji usług, która implementuje oba interfejsy. Poniżej znajduje się pełny działający kod.

Serwer:

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

Klient:

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 kontraktu:

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

    [OperationContract] 
    string FooMethod2(); 
} 

Bar kontraktu:

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

    [OperationContract] 
    string BarMethod2(); 
} 

Foo Usługa:

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

Bardzo podoba mi się, że opublikowałeś swój kod wyniku końcowego - to pomaga innym, mi włącznie. Widzę komentarze, takie jak ja opublikuję ostateczny kod; a przecież ludzie po prostu tego nie robią i zostawiam walenie w głowę! ++ – Stix

+0

Fajny kod, ale jeśli jestem w WCF hostowanym na IIS, gdzie mogę umieścić rzeczy, które są w Main? – Rhyous

+0

To byłoby w obszarze usługi WCF, która inicjuje rzeczy podczas uruchamiania usługi. Gdzie obecnie ustawiasz wiązania i punkty końcowe? Właśnie tam powinien iść ten kod. –

Powiązane problemy