2010-03-23 3 views
2

У меня есть только простые типы данных в сигнатуре метода службы (например, int, string). Мой класс сервиса реализует один интерфейс ServiceContract, говорят IMathService, и этот интерфейс, в свою очередь, наследуется от какого-то другого базового интерфейса, скажем, IAdderService. Я хочу открыть MathService, используя интерфейс IAdderService, как службу на одной конечной точке. Однако некоторые из клиентов, которые знают об IMathService, должны иметь доступ к дополнительным услугам, предоставляемым 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> 

Используя выше кода и конфигурации, я не в состоянии typecast 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); 

Это работает для меня. Вы не можете использовать базовый тип для производного типа. Однако вы можете сделать обратное.

Смежные вопросы