Подтвердить что ты не робот

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

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

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

"Типы повторного использования в ссылочных сборках" позволяет вам повторно использовать Контракты данных, а не Сервисные контракты. Если вы хотите использовать Сервисные контракты, вам не нужно использовать "Добавить ссылку на службу" вообще. Вы можете напрямую использовать 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 ().

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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

internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService
{}

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

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

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

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