2010-03-23 8 views
2

Je n'ai que des types de données simples dans la signature de méthode de service (int, chaîne). Ma classe de service implémente une seule interface ServiceContract, par exemple IMathService, et cette interface hérite à son tour d'une autre interface de base, par exemple IAdderService. Je souhaite exposer MathService à l'aide du contrat d'interface IAdderService en tant que service sur un seul noeud final. Cependant, certains des clinets qui connaissent IMathService devraient être en mesure d'accéder aux services supplémentaires fournis par IMathService sur ce point de terminaison unique, c'est-à-dire simplement en typant IAdderService en IMathService.Comment exposer des interfaces de contrat de service avec héritage multiple dans le service WCF sur un seul point de terminaison

//Interfaces and classes at server side 
[ServiceContract] 
public interface IAdderService 
{ 
[OperationContract] 
int Add(int num1, int num2); 
} 

[ServiceContract] 
public interface IMathService : IAdderService 
{ 
[OperationContract] 
int Substract(int num1, int num2); 
} 

public class MathService : IMathService 
{ 
#region IMathService Members 
public int Substract(int num1, int num2) 
{ 
    return num1 - num2; 
} 
#endregion 

#region IAdderService Members 
public int Add(int num1, int num2) 
{ 
    return num1 + num2; 
} 
#endregion 
} 

//Run WCF service as a singleton instace 
MathService mathService = new MathService(); 
ServiceHost host = new ServiceHost(mathService); 
host.Open(); 

Configuration côté serveur:

<configuration> 
    <system.serviceModel> 
    <services> 
      <service name="IAdderService" 
     behaviorConfiguration="AdderServiceServiceBehavior"> 
     <endpoint address="net.pipe://localhost/AdderService" 
     binding="netNamedPipeBinding" 
     bindingConfiguration="Binding1" 
     contract="TestApp.IAdderService" /> 
     <endpoint address="mex" 
     binding="mexNamedPipeBinding" 
     contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="net.pipe://localhost/AdderService"/> 
      </baseAddresses> 
     </host> 
      </service> 
      </services> 
     <bindings> 
     <netNamedPipeBinding> 
     <binding name="Binding1" > 
      <security mode = "None"> 
      </security> 
      </binding > 
     </netNamedPipeBinding> 
     </bindings> 

     <behaviors> 
     <serviceBehaviors> 
    <behavior name="AdderServiceServiceBehavior"> 
      <serviceMetadata /> 
     <serviceDebug includeExceptionDetailInFaults="True" /> 
    </behavior> 
     </serviceBehaviors> 
     </behaviors> 
    </system.serviceModel> 
    </configuration> 

côté client imeplementation:

IAdderService adderService = new 
ChannelFactory<IAdderService>("AdderService").CreateChannel(); 
int result = adderService.Add(10, 11); 

IMathService mathService = adderService as IMathService; 
result = mathService.Substract(100, 9); 

configuration côté client:

<configuration> 
     <system.serviceModel> 
      <client> 
      <endpoint name="AdderService" address="net.pipe://localhost/AdderService" binding="netNamedPipeBinding" bindingConfiguration="Binding1" contract="TestApp.IAdderService" /> 
      </client> 

      <bindings> 
      <netNamedPipeBinding> 
     <binding name="Binding1" maxBufferSize="65536" maxConnections="10"> 
      <security mode = "None"> 
      </security> 
     </binding > 
      </netNamedPipeBinding> 
      </bindings> 
     </system.serviceModel> 
     </configuration> 

En utilisant code ci-dessus et la configuration Je ne suis pas en mesure de catalogué IAdd erService instnace à IMathService, il échoue et j'obtiens une instance nulle de IMathService côté client. Mon observation est que si le serveur expose IMathService au client, alors le client peut en toute sécurité transtyper en IAdderService et vice versa est également possible. Toutefois, si le serveur expose IAdderService, le typecast échoue.

Y at-il une solution à cela? ou est-ce que je le fais d'une mauvaise manière.

Répondre

0

Comme vous l'avez observé, vous devez exposer le service dérivé (MathService) au lieu de AdderService.

WCF n'a aucune idée que AdderService se trouve être un MathService implémentant une interface MathService. Il est considéré comme AdderService - il n'y a donc aucun moyen de le convertir en une classe dérivée.

0

J'ai répliqué votre situation exactement, sauf que j'ai utilisé un point de terminaison IMathService plutôt qu'un point de terminaison IAdderService.

IAdderService adderService = new ChannelFactory<IMathService>("MathService").CreateChannel(); 
int result = adderService.Add(10, 11); 

IMathService mathService = adderService as IMathService; 
result = mathService.Substract(100, 9); 

Cela fonctionne pour moi. Vous ne pouvez pas convertir un type de base en un type dérivé. Vous pouvez faire l'inverse cependant.