Comment exposer les interfaces contrat de service avec l'héritage multiple dans le service WCF sur simple point final

StackOverflow https://stackoverflow.com/questions/2500336

  •  21-09-2019
  •  | 
  •  

Question

Je n'ai que des types de données simples dans la signature de la méthode de service (tels que int, string). Ma classe de service implémente une interface unique de ServiceContract dire IMathService, et cette interface hérite à son tour d'une autre interface de base IAdderService dire. Je veux exposer le IAdderService contrat d'interface à l'aide MathService en tant que service sur un seul point de terminaison. Cependant, certains de la Clinet qui sait au sujet IMathService devrait être en mesure d'accéder aux services supplémentaires fournis par IMathService sur ce seul point final à savoir en tout typecasting IAdderService à IMathService.

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

côté serveur Configuration:

 <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 du 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 le code ci-dessus et la configuration Je ne suis pas en mesure de typer IAdderService instnace à IMathService, il échoue et je reçois sans instance de IMathService à côté client.

Mon observation est si le serveur expose IMathService au client alors client peut en toute sécurité cataloguée à IAdderService et vice versa est également possible. Toutefois, si le serveur expose IAdderService alors le typecast échoue.

Y at-il une solution à cela? ou que je fais dans un mauvais sens.

Était-ce utile?

La solution

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

WCF n'a aucune idée que AdderService se trouve être en fait une MathService mise en œuvre d'une interface MathService. Il est considéré comme AdderService -. Il n'y a aucun moyen de le jeter à une classe dérivée

Autres conseils

Je répliqués votre situation exactement, sauf que j'utilisé un point de terminaison IMathService plutôt que d'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 lancer un type de base à un type dérivé. Vous pouvez faire l'inverse cependant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top