2010-03-23 61 views
2

我在服务的方法签名(例如int,string)中只有简单的数据类型。我的服务类实现了单一的ServiceContract接口,比如说IMathService,而这个接口又继承了一些其他的基本接口,比如说IAdderService。我想在单个端点上使用接口协定IAdderService作为服务公开MathService。然而,一些了解IMathService的clinet应该能够访问IMathService在该单个端点上提供的额外服务,即只需将IAdderService类型化为IMathService即可。如何在单个端点上公开WCF服务中具有多继承的服务契约接口

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

客户端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> 
     <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> 

使用上面的代码和配置,我不能类型转换IAdd erService instnace到IMathService,它失败,我在客户端获得IMathService的空实例。

我的观察是,如果服务器向客户端公开IMathService,则客户端可以安全地向IAdderService进行类型转换,反之亦然。但是,如果服务器公开IAdderService,则该类型转换失败。

有没有解决这个问题的方法?或者我是以一种错误的方式去做的。

回答

0

正如您所观察到的,您必须公开派生服务(MathService)而不是AdderService。

WCF不知道AdderService碰巧实际上是实现MathService接口的MathService。它被视为AdderService - 因此无法将其转换为派生类。

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

这适用于我。您不能将基类型转换为派生类型。但是,你可以做相反的事情。