Наследование службы WCF - PullRequest
4 голосов
/ 06 августа 2010

У меня ОЧЕНЬ комплексный хост-сервис, состоящий из нескольких сервисов DUPLEX. Они предоставляют немного общих функций (Connect, Disconnect, KeepAlive и т. Д.), Но помимо этого они предоставляют очень специфические функции для каждого.

Все мои сервисы наследуются от общего базового класса (аннотация).

Итак, я также отвечаю за часть клиентского приложения и хочу, чтобы административная бюрократическая обработка соединения, разъединения, поддержания связи, проверки связи и повторного соединения (и т. Д.) Обрабатывалась в базовом классе, чтобы я мог соблюдайте принцип СУХОГО И заставляйте других разработчиков НЕ реализовывать свою собственную обработку соединений.

Есть ли ЛЮБОЙ способ сделать так, чтобы WCF предоставил базовый класс обслуживания, чтобы я мог создать общий класс-обертку для бюрократической траты времени в клиентском приложении?

Я действительно не хочу, чтобы каждый разработчик будущих клиентских компонентов создавал свою собственную оболочку?

И, если вы позволите разглагольствовать:

Почему, почему, почему Microsoft так небрежно относится к лучшим практикам и базовым принципам разработки чистого кода? Это то же самое, что и с этим INotifyPropertyChanged - материал, в котором каждый вынужден писать массу ненужного повторяющегося кода вместо того, чтобы получить простой атрибут для уведомления свойств ...

1 Ответ

5 голосов
/ 07 августа 2010

Я не знаю хорошего способа сделать так, чтобы несколько прокси 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));

(В рабочем коде вы захотите повторно использовать фабрики каналов, а не создавать их «на лету», как это. И вы бы избавились от прокси, и у вас была бы обработка ошибок ...)

Вам также необходимо настроить конечные точки в файле конфигурации клиента.

Если у вас есть два прокси-сервера, использующих общий интерфейс, вы можете написать служебный класс, который поможет вам работать с этим интерфейсом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...