2

サービスのメソッド シグネチャには単純なデータ型しかありません (int、string など)。私のサービス クラスは、IMathService などの単一の ServiceContract インターフェイスを実装し、このインターフェイスは IAdderService などの他の基本インターフェイスから継承します。インターフェイス コントラクト IAdderService を使用して、MathService を単一のエンドポイントのサービスとして公開したいと考えています。ただし、IMathService を知っている一部のクライアントは、IMathService に 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();

サーバー側の構成:

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

クライアント側の実装:

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

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

クライアント側の構成:

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

上記のコードと構成を使用すると、IAdderService インスタンスを IMathService に型キャストできません。失敗し、クライアント側で IMathService の null インスタンスを取得します。

私の観察では、サーバーが IMathService をクライアントに公開すると、クライアントは安全に IAdderService にタイプキャストでき、その逆も可能です。ただし、サーバーが IAdderService を公開している場合、型キャストは失敗します。

これに対する解決策はありますか?または私は間違った方法でそれをやっていますか。

4

2 に答える 2

0

ご覧のとおり、AdderService の代わりに派生サービス (MathService) を公開する必要があります。

WCF は、AdderService がたまたま実際に MathService インターフェイスを実装する MathService であることを認識していません。AdderService と見なされるため、派生クラスにキャストする方法はありません。

于 2010-03-23T19:09:09.450 に答える
0

IMathServiceエンドポイントではなくエンドポイントを使用したことを除いて、状況を正確に再現しましたIAdderService

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

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

これは私にとってはうまくいきます。基本型を派生型にキャストすることはできません。ただし、逆にすることもできます。

于 2010-06-16T20:02:14.850 に答える