开发者

Interface(s) inheriting other interface(s) in WCF services

开发者 https://www.devze.com 2023-01-02 00:21 出处:网络
In my solution there\'s a few WCF services, each of them implementing it\'s own callback interface. Let\'s say they are called: Subscribe1, with ISubscribe1 and ICallback1, etc.

In my solution there's a few WCF services, each of them implementing it's own callback interface. Let's say they are called: Subscribe1, with ISubscribe1 and ICallback1, etc.

It happens there are a few methods shared among ICallbacks, so I made a following interface:

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

and i inherited it in all: ICallback1 : ICallback, ICallback2 : ICallback, etc. And deleted the CommonlyUsedMethod() from all callback interfaces.

Now, on the service-side code, everything compiles fine and services can start working as usual. But, when I updated the service references for the client, CommonlyUsedMethod() diss开发者_如何学Pythonapeared from the reference.cs file (the ISubscribeCallback part), and could no longer be used to send data to back to the client.


try to set the ServiceContract attribute on the base interface also.


Ok, this is the exact code, I condensed it as much as I can. Just start a new console application and copy/paste it. Start it and add a service reference to it. CommonlyUsedMethod() is not present in the reference, while the other methods are. Could it be framework 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()
        {
        }
    }
}


Does this reflect what you have in your code?

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

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

This is essentially the structure I have in my production solution, and then I use the proxies that are generated when I add a Service Reference to access my methods from the client.

For reference, the generated interface then looks like this:

[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();

}

Note the "ICallbackBase" in the OperationContractAttribute - it really does know where the method came from.


I'm not sure that what you are trying to do using WCF is possible. When you use inheritance in WCF you need to apply the KnownType attribute to the DataContract so that the DataContractSerializer will know to serialize it and make it available on the other end. Since you cannot put the KnownType attribute on interfaces, there is no way to tell the serializer that this is needed on the other end. Thus is does not show up when you implement it on the client.

0

精彩评论

暂无评论...
验证码 换一张
取 消