Почему мой сгенерированный клиентский класс не наследуется от интерфейса ServiceContract? - PullRequest
0 голосов
/ 11 февраля 2011

Я недавно начал использовать WCF и с удивлением обнаружил, что класс клиента, сгенерированный Add Service Reference, не реализует интерфейс ServiceContract (назовем его IMyInterface).Вместо этого он реализует System.ServiceModel.ClientBase<IAnotherInterface>, IAnotherInterface, где IAnInterface - это интерфейс, который похож на мой интерфейс ServiceContract, но на самом деле не тот же.Я вижу, что некоторые типы отличаются, например, вместо списков в нем есть массивы.

Это немного раздражает меня, так как иногда я хочу делать удаленные вызовы веб-службы, а иногда хочу использовать локальный объект, поэтому я хочу, чтобы они реализовали один и тот же интерфейс.В настоящее время я обертываю объект ClientBase в другой, чтобы он реализовывал тот же интерфейс, и просто передаю все вызовы объекту ClientBase.Это рекомендуемый подход или есть более простой способ?

Я вижу, что могу изменить типы параметров коллекции с массива на Список или что-то еще в Configure Service Reference, но сомневаюсь, что это решит основную проблему типизации.

Ответы [ 3 ]

2 голосов
/ 11 февраля 2011

Я думаю, что вы хотите переместить свои сервисные интерфейсы в отдельную библиотеку (DLL / проект).

Тогда возникает перегрузка SvcUtil.exe , которая позволяет вам генерировать клиентПрокси, передаваемые в библиотеку (DLL) интерфейсов, чтобы они не дублировались.Я думаю, что флаг -r или -reference или что-то в этом роде ...

1 голос
/ 11 февраля 2011

Вам не нужно использовать ссылку «Добавить службу» или SvcUtil. Вы можете вручную создать клиентский прокси, который использует ваш интерфейс. Вам понадобится привязка в вашем web.config, чтобы использовать конструктор по умолчанию, или вы можете передать конечную точку и привязку.

Одним из больших преимуществ этого метода является то, что вам не нужно возиться с SvcUtil.exe каждый раз, когда вы меняете интерфейс и вам необходимо повторно создать прокси. Вместо этого вы получите ошибку компиляции, напоминающую, что этот класс неправильно реализует ваш интерфейс.

SvcUtil и Add Service Reference в основном используются для удаленных сервисов, где у вас нет доступа к исходному интерфейсу сервиса или контрактам. Утилита просто читает сервис wsdl и генерирует его для вас. Отсюда и сумасшедшее название, чтобы убедиться, что оно не конфликтует с чем-то, что уже есть в вашем проекте.

Кроме того, как упоминал Reddog, перемещение ваших контрактов на обслуживание и передачу данных в другой проект / dll позволяет вам легче ссылаться на них.

public partial class MyServiceClient : System.ServiceModel.ClientBase<MyProject.Contracts.IMyService>, MyProject.Contracts.IMyService
  {

    #region IMyService Members

    public void RecordSearchAnalytics(int a, int b, int c, string d, string e)
    {
      base.Channel.RecordSearchAnalytics(a, b, c, d, e);
    }

    #endregion

    #region boiler plate code 
    public MyHServiceClient()
    {
    }

    public MyHServiceClient(string endpointConfigurationName) :
      base(endpointConfigurationName)
    {
    }

    public MyHServiceClient(string endpointConfigurationName, string remoteAddress) :
      base(endpointConfigurationName, remoteAddress)
    {
    }

    public MyHServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
      base(endpointConfigurationName, remoteAddress)
    {
    }

    public MyHServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
      base(binding, remoteAddress)
    {
    }

    #endregion




  }
0 голосов
/ 11 февраля 2011

Поведение по умолчанию для WCF именно то, что вы видите: служба и клиент полностью независимы друг от друга - в конце концов, с идеей совместимости вы не можете полагаться на то, что клиент .NET тоже - это может быть Ruby, Python - вы называете это.

Таким образом, когда клиентский прокси создается, единственное, что клиент и общий ресурс службы - это формат сообщений на проводе, а в случае SOAP - WSDL-описание службы. Прокси-сервер на стороне клиента воссоздается на основе этих метаданных с целью предоставления одних и тех же методов для вызова и тех же структур данных, которые будут использоваться для сериализации сообщений службе.

Если вы можете контролировать оба конца связи, и оба они являются .NET, то вы можете пропустить один из этих шагов, поместив ваши сервисы и контракты данных в отдельную библиотеку классов и поделившись этой сборкой (и, следовательно, этими точными интерфейсами и классы) между сервисом и клиентом.

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

...