Интерфейс (ы), наследующий другой интерфейс (ы) в сервисах WCF - PullRequest
3 голосов
/ 01 июня 2010

В моем решении есть несколько сервисов WCF, каждый из которых реализует свой собственный интерфейс обратного вызова. Допустим, они называются: Subscribe1, с ISubscribe1 и ICallback1 и т. Д.

Бывает, что ICallbacks использует несколько методов, поэтому я создал следующий интерфейс:

interface ICallback
{
    [OperationContract]
    void CommonlyUsedMethod();
}

и я унаследовал его во всех: ICallback1 : ICallback, ICallback2 : ICallback и т. Д. И удалил CommonlyUsedMethod() из всех интерфейсов обратного вызова.

Теперь в коде на стороне службы все прекрасно скомпилируется, и службы могут начать работать как обычно. Но когда я обновил сервисные ссылки для клиента, CommonlyUsedMethod () исчез из файла reference.cs (часть ISubscribeCallback) и больше не мог использоваться для отправки данных обратно клиенту.

Ответы [ 4 ]

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

попробуйте также установить атрибут ServiceContract на базовом интерфейсе.

1 голос
/ 01 июня 2010

Хорошо, это точный код, я сжал его столько, сколько смог.Просто запустите новое консольное приложение и скопируйте / вставьте его.Запустите его и добавьте ссылку на сервис.CommonlyUsedMethod () отсутствует в ссылке, в то время как другие методы есть.Это может быть фреймворк 4?

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace TestService
{
    class Program
    {
        static void Main()
        {
            var serviceHost=new ServiceHost(typeof(Subscribe1), new Uri("net.tcp://localhost:8888"));
            serviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior());
            serviceHost.AddServiceEndpoint(typeof(ISubscribe1), new NetTcpBinding(SecurityMode.None), string.Empty);
            serviceHost.AddServiceEndpoint("IMetadataExchange", MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
            serviceHost.Open();

            Console.WriteLine("Working!");
            while(Console.ReadKey(true).Key!=ConsoleKey.Escape) { }
        }
    }

    [ServiceContract]
    interface ICallbackBase
    {
        [OperationContract]
        void CommonlyUsedMethod();
    }

    [ServiceContract]
    interface ICallback1 : ICallbackBase
    {
        [OperationContract]
        void SpecificMethod();
    }

    [ServiceContract(CallbackContract=typeof(ICallback1))]
    interface ISubscribe1
    {
        [OperationContract]
        void TestMethod();
    }

    [ServiceBehavior]
    class Subscribe1 : ISubscribe1
    {
        [OperationBehavior]
        public void TestMethod()
        {
        }
    }
}
0 голосов
/ 01 июня 2010

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

0 голосов
/ 01 июня 2010

Отражает ли это то, что у вас есть в коде?

[ServiceContract]
public interface ICallbackBase
{
    [OperationContract]
    void CommonlyUsedMethod();
}

[ServiceContract]
public interface ICallback1 : ICallbackBase
{
    [OperationContract]
    void SpecificMethod();
}

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

Для справки сгенерированный интерфейс выглядит следующим образом:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="MyNamespace.ICallback1")]
public interface ICallback1 {

    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICallbackBase/CommonlyUsedMethod", ReplyAction="http://tempuri.org/ICallbackBase/CommonlyUsedMethodResponse")]
    void CommonlyUsedMethod();

}

Обратите внимание на «ICallbackBase» в OperationContractAttribute - он действительно знает, откуда появился метод.

...