WCF Service Reference генерирует свой собственный интерфейс контракта, не будет повторно использовать мой - PullRequest
37 голосов
/ 25 июня 2010

Мой первый вопрос, поэтому надеюсь, что он подходит:

Совместно используемая сборка интерфейса - У меня есть «общая» сборка с интерфейсом, назовем ее IDocRepository.Он помечен [ServiceContract] и имеется несколько [OperationContract] помеченных методов.

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

Потребительская сборка - Наконец, у меня есть «клиентский» проект, также ссылающийся на общую сборку, со ссылкой на каждую из двух служб WCF.

Однако ссылки на службы, сгенерированные в потребительской сборке, основаны на автоматически сгенерированной версии интерфейса:

public partial class ExampleClient : System.ServiceModel.ClientBase<SomeNamespace.ExampleSvcRef.IDocRepository>, SomeNamespace.ExampleSvcRef.IDocRepository {

Что я ожидал
Я бы надеялся, чтовместо этого обе ссылки будут автоматически наследовать определенный мной интерфейс, на который ссылается также потребитель / клиентская сборка.Вроде как повторное использование классов, которые оно предоставляет для параметров и типов возврата, но для интерфейса службы.

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

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

(редактировать: у меня естьПараметры «Повторное использование типов в ссылочных сборках» и «Повторное использование типов во всех ссылочных сборках», выбранные для обеих ссылок на услуги)

Ответы [ 4 ]

45 голосов
/ 26 июня 2010

«Повторное использование типов в ссылочных сборках» позволяет только повторно использовать Контракты на данные, а не Контракты на обслуживание.Если вы хотите поделиться Договорами на обслуживание, вам вообще не нужно использовать «Добавить ссылку на обслуживание».Вы можете просто использовать ChannelFactory напрямую.

// Supply the binding and address in code
Binding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress("http://tempuri.org/address");
IServiceContract channel = ChannelFactory<IServiceContract>.CreateChannel(binding, address);

// Or read them from the config file
ChannelFactory<IServiceContract> channelFactory = new ChannelFactory<IServiceContract>();
IServiceContract channel = channelFactory.CreateChannel();

Объект канала также будет реализовывать ICommunicationObject , поэтому вы можете привести его, если вам нужно вызвать методы, такие как Open () или Close ().

4 голосов
/ 25 июня 2010

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

Если он по-прежнему не работает, проверьте используемую привязку.У меня есть смутное воспоминание, что базовая HTTP-привязка не будет поддерживать повторное использование типов?

3 голосов
/ 26 июня 2013

Visual Studio не поддерживает повторное использование существующего интерфейса при создании прокси-классов для вас. Повторное использование типов не будет повторно использовать интерфейс контракта, как указал Quartermeister.

Мы решили это по наследству. Совершенно похоже на идею частичного класса, предложенную выше Jester Software.

Вот как мы это решили:

В проекте вашего клиента просто создайте сервисную ссылку, как вы бы сделали. Затем добавьте класс, который служит заменой для клиента:

internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService
{}

Этот класс наследует от сгенерированного MyServiceClient, но утверждает, что этот клиент реализует оригинальный интерфейс.

(я предлагаю вам поместить их в папку с именем «ServiceProxies»)

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

После этого просто используйте MyServiceProxy, где вы бы использовали MyServiceClient.

2 голосов
/ 02 сентября 2011

Есть еще один хороший вариант, если вы хотите продолжать использовать прокси-генератор для его ограниченной, но несколько полезной функциональности ... Используйте частичный класс:

namespace <same namespace as generated proxy>
{
    public partial class MyClient : <namespace of "real" service contract>.IServiceContract
    {
    }
}

Убедитесь, что прокси-сервер генерирует код так же, как это определяет ваш контракт на обслуживание, т. Е. Если он использует «Список», используйте эту опцию и в разделе «Настройка ссылок на услуги». Другими словами, убедитесь, что ваш сгенерированный интерфейс службы в точности совпадает с реальным интерфейсом службы, и приведенный выше код должен работать, и для обновления ссылки вы используете щелчок правой кнопкой мыши вместо написания кода.

...