Я не знаю хорошего способа сделать так, чтобы несколько прокси WCF наследовали из общего базового класса. Вы можете вручную редактировать код, который генерируется при добавлении ссылки на службу, но это не очень хорошо для удобства обслуживания.
Но вы можете иметь несколько прокси-серверов, использующих один и тот же базовый интерфейс, если вы разделяете контрактную сборку между клиентом и сервером. Затем вы могли бы написать вспомогательный класс на стороне клиента (возможно, используя методы расширения) для выполнения общих операций с базовым интерфейсом. Вы также можете поместить вспомогательный класс в общую сборку и повторно использовать его для нескольких клиентов.
Хотя я не работал с дуплексными привязками, поэтому я не уверен, вызывает ли это осложнения.
Например, предположим, у вас есть две службы Calculator и Echo, и каждая из них должна реализовать метод Keepalive. Вы можете определить три интерфейса контракта на обслуживание:
[ServiceContract]
public interface IStatefulService
{
[OperationContract]
void KeepAlive(int sessionID);
}
[ServiceContract]
public interface ICalculator : IStatefulService
{
[OperationContract]
int Add(int a, int b);
}
[ServiceContract]
public interface IEcho : IStatefulService
{
[OperationContract]
string Echo(string message);
}
Вы можете поместить интерфейсы контрактов на обслуживание в общую библиотеку классов, которая используется как клиентом, так и сервером.
На сервере у вас будет класс ServiceBase, который будет реализовывать IStatefulService и содержать код обработки keepalive. У вас будет конкретный CalculatorService, который наследуется от ServiceBase и реализует ICalculator; и конкретный EchoService, производный от ServiceBase и реализующий IEcho.
На клиенте вам понадобятся два прокси, по одному на службу. Теоретически, вы можете сгенерировать прокси, используя «добавить ссылку на службу», используя флажок «повторное использование типов из ссылочных сборок», но у меня возникли проблемы с этим. Вместо этого вы можете просто использовать ChannelFactory напрямую, например так:
var echoer = (new ChannelFactory<IEcho>("")).CreateChannel();
Console.WriteLine(echoer.Echo("hello"));
var calculator = (new ChannelFactory<ICalculator>("")).CreateChannel();
Console.WriteLine(calculator.Add(2, 3));
(В рабочем коде вы захотите повторно использовать фабрики каналов, а не создавать их «на лету», как это. И вы бы избавились от прокси, и у вас была бы обработка ошибок ...)
Вам также необходимо настроить конечные точки в файле конфигурации клиента.
Если у вас есть два прокси-сервера, использующих общий интерфейс, вы можете написать служебный класс, который поможет вам работать с этим интерфейсом.