Note---Operation Overloading and Contract Inheritance

Operation Overloading

WCF Service does not explicitly support the operation overloading ,the following snippet code will throw a exception at the service host load time:

[ServiceContract]
interface ICalculator
{
    [OperationContract]
    int Add(int x, int y);

    [OperationContract]
    double Add(double x, double y);
}

the developer can avoid this exception but without updating the operation name by aliasing the operation name using Name property of OperationContract attribute. the following snippet shows what we should do:

   [ServiceContract]
    interface ICalculator
    {
        [OperationContract(Name="AddInt")]
        int Add(int x, int y);

        [OperationContract(Name="AddDouble")]
        double Add(double x, double y);
    }

as we see here, we do fix the overloading problem at the service side with the help of the Name property, but how does the corresponding client perform this? unfortunately it does not work as we thought, just working with the alias name of the operation  as following:

public interface ICalculator {
       [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculator/AddInt",
           ReplyAction="http://tempuri.org/ICalculator/AddIntResponse")]
       int AddInt(int x, int y);
       [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculator/AddDouble",
           ReplyAction="http://tempuri.org/ICalculator/AddDoubleResponse")]
       double AddDouble(double x, double y);
   }

as see here ,which is not our so-called overloading, but we can restore the overloading hierarchy on the client side manually as following snippet shows:

[ServiceContract]
 public interface ICalculator {
     [OperationContract(Name="AddInt")]
     int Add(int x, int y);
     [OperationContract(Name="AddDouble")]
     double Add(double x, double y);
 }

Do what we have done on the server side for the client using the name property(the name on the client side must match up with the name at on the server side), and this is not enough, we also should update the client proxy as following:

public int AddInt(int x, int y) {
          return base.Channel.Add(x, y);
      }
      public double AddDouble(double x, double y) {
          return base.Channel.Add(x, y);
      }

so what we have done on the cilent side makes the client be overloading. so amazing!

Contract Inheritance

Service contract can inherit from other Service contracts, but the ServiceContract attribute is not inheritable, so every service contract muct explicitly apply the ServiceContract attribute.the following code shows how service contract inheritance works:

[ServiceContract]
   interface ISimpleCalculator
   {
       [OperationContract]
       double Add(double x, double y);
   }

[ServiceContract]
    interface ICalculator:ISimpleCalculator
    {
        [OperationContract]
        double Mutiply(double x, double y);
    }

public class CalculatorService:ICalculator
    {
        public double Mutiply(double x, double y)
        {
            return x*y;
        }

        public double Add(double x, double y)
        {
            return x = y;
        }
    }

the host can expose a single endpoint for the bottom contract interface in the hierarchy.the following code is the host endpoint configuration:

<endpoint address="http://localhost:8080/calculatorService"
                 binding="wsHttpBinding"
                 contract="WCFOO.Server.ICalculator">
       </endpoint>

as we supposed, host only exposes a single endpoint and contract is the bottom contract in the hierarchy.

as the same as we made about the operation overloading above,this is about the inheritance on the server side, and how does it work on the client side, as unfortunate as the operation overloading does on the client side, the inheritance hierarchy is not maintained on the client side. it becomes to be a flattened hierarchy.

client code for contract:

[ServiceContract]
   public interface ICalculator {
       [OperationContract(Action="http://tempuri.org/ISimpleCalculator/Add",
           ReplyAction="http://tempuri.org/ISimpleCalculator/AddResponse")]
       double Add(double x, double y);
       [OperationContract(Action="http://tempuri.org/ICalculator/Mutiply",
           ReplyAction="http://tempuri.org/ICalculator/MutiplyResponse")]
       double Mutiply(double x, double y);
   }

as we see, the operations use the Action and ReplyAction to find their real contract(here i didnot specify the namespace of the service so it’s the default namespace)

part of client code for service proxy:

public double Add(double x, double y) {
            return base.Channel.Add(x, y);
        }
        public double Mutiply(double x, double y) {
            return base.Channel.Mutiply(x, y);
        }

so disappointed, there is no sign showing the inheritance hierarchy, but we can also restore the client code to make the client work like what we want as we did about the operation overloading.

we can add the hierachy manually as the client code:

[ServiceContract]
    public interface ISimpleCalculator
    {
        [OperationContract]
        double Add(double x, double y);
    }

    [ServiceContract]
    public interface ICalculator : ISimpleCalculator
    {
        [OperationContract]
        double Mutiply(double x, double y);
    }
    public partial class SimpleCalculatorClient : ClientBase<ISimpleCalculator>,
        ISimpleCalculator
    {
        public double Add(double x, double y)
        {
            return this.Channel.Add(x, y);
        }
    }

     public interface ICalculatorChannel : ICalculator, IClientChannel {
    }
    public partial class CalculatorClient : ClientBase<ICalculator>,
        ICalculator
    {
        public CalculatorClient() {
        }
        public double Add(double x, double y) {
            return base.Channel.Add(x, y);
        }
        public double Mutiply(double x, double y) {
            return base.Channel.Mutiply(x, y);
        }
    }

and the client configuration should be changed simultaneously exposing two endpoints.

<client>
          <endpoint address="http://localhost:8080/calculatorService"
                    binding="wsHttpBinding"
                    contract="WCFOO.Client.CalculatorService.ICalculator" >
          </endpoint>
        <endpoint address="http://localhost:8080/calculatorService"
                    binding="wsHttpBinding"
                    contract="WCFOO.Client.CalculatorService.ISimpleCalculator" >
        </endpoint>
      </client>

but the endpoint for server is still a single one without any changes.

late again today, i do not want to stay up here, this is not complete and leave it tomorrow.

转载于:https://www.cnblogs.com/sanjia/archive/2011/06/08/2074733.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值