我们在应用WCF服务契约的时候,需要掌握一些应用技巧,才能帮助我们轻松的应用这一功能来完成各种功能需求。在这里我们就一起来看看WCF服务契约的分解与设计方法,以方便大家理解。
C++与C#均支持操作的重载,但在WCF的编程模型中,却并不支持这种技术。坦白说,在WCF的编程模型,对于面向对象的支持都是比较弱的,包括后面要介绍的继承体系与多态,都存在许多问题。因此,在服务端我们不能定义这样的WCF服务契约:
- [ServiceContract]
- interface ICalculator
- {
- [OperationContract]
- int Add(int arg1,int arg2);
- [OperationContract]
- double Add(double arg1,double arg2);
- }
虽然在编译时能够通过,然而一旦在装载宿主时,就会抛出InvalidOperationException异常。以ICalculator契约为例,WCF会认为是零个操作。
解决的办法是利用OperationContract特性的Name属性,例如:
- [ServiceContract]
- interface ICalculator
- {
- [OperationContract(Name = "AddInt")]
- int Add(int arg1,int arg2);
- [OperationContract(Name = "AddDouble")]
- double Add(double arg1,double arg2);
- }
不过采用这种方式,存在的问题是生成的代理会将Name属性指定的名称作为代理操作的方法名。这对于编程者而言,并非好的方式。所幸我们可以手动对生成的代理进行修改,将它修改为与WCF服务契约一致的操作名。由于,此时通过Name指定了操作的别名,因此,避免了装载宿主抛出的异常。
契约的继承
即使父接口标记了[ServiceContract],子接口仍然需要标记[ServiceContract],因为ServiceContractAttribute是不可继承的。服务类对服务契约的实现,与传统的C#编程没有什么区别。例如:
- [ServiceContract]
- interface ISimpleCalculator
- {
- [OperationContract]
- int Add(int arg1,int arg2);
- }
- [ServiceContract]
- interface IScientificCalculator : ISimpleCalculator
- {
- [OperationContract]
- int Multiply(int arg1,int arg2);
- }
- class MyCalculator : IScientificCalculator
- {
- public int Add(int arg1,int arg2) { return arg1 + arg2;
- }
- public int Multiply(int arg1,int arg2) { return arg1 * arg2;
- }
- }
公开终结点的时候,可以对***层的契约接口公开一个单独的终结点:
- < service name=”MyCalculator”> < endpoint> < addressaddress=
”http://localhost:8001/MyCalculator/”> < bindingbinding=
”basicHttpBinding”> < contractcontract=” IScientificCalculator”>
< /endpoint> < /service>
客户端在导入如上的WCF服务契约时,会取消服务契约的继承层级,并利用OperationContract特性中的Action与ReplyAction属性,保留原来定义每个操作的契约名。但为了使客户端编程能够与服务编程保持一致,***是恢复客户端的契约层级。方法并无什么太玄妙的地方,无非就是根据服务契约层级对客户端契约进行手工修改。修改后的客户端契约及其代理的定义如下:
- [ServiceContract]
- public interface ISimpleCalculator {
- [OperationContract]
- int Add(int arg1,int arg2);
- }
- public partial class SimpleCalculatorClient : ClientBase
< ISimpleCalculator>, ISimpleCalculator- {
- public int Add(int arg1,int arg2)
- {
- return Channel.Add(arg1,arg2);
- } //Rest of the proxy }
- [ServiceContract]
- public interface IScientificCalculator : ISimpleCalculator {
- [OperationContract]
- int Multiply(int arg1,int arg2);
- }
- public partial class ScientificCalculatorClient : ClientBase
< IScientificCalculator>,IScientificCalculator {- public int Add(int arg1,int arg2) {
- return Channel.Add(arg1,arg2); }
- public int Multiply(int arg1,int arg2) {
- return Channel.Multiply(arg1,arg2); }
- //Rest of the proxy }
在书中还提出了所谓的代理链(Proxy Chaining)技术,实质上就是使得分别实现不同层级接口的代理类形成一个IS-A的继承关系。如上的定义,就可以使ScientificCalculatorClient继承自SimpleCalculatorClient,而不是继承ClientBase< IScientificCalculator>:
- public partial class SimpleCalculatorClient :
ClientBase< IScientificCalculator>, ISimpleCalculator {- public int Add(int arg1,int arg2) {
- return Channel.Add(arg1,arg2);
- } //Rest of the proxy }
- public class ScientificCalculatorClient : SimpleCalculatorClient,
IScientificCalculator {- public int Multiply(int arg1,int arg2) {
- return Channel.Multiply(arg1,arg2); } //Rest of the proxy }
只有这样,如下代码才是正确的:
- SimpleCalculatorClient proxy1 = new SimpleCalculatorClient( );
- SimpleCalculatorClient proxy2 = new ScientificCalculatorClient( );
- ScientificCalculatorClient proxy3 = new ScientificCalculatorClient( );
以上就是对WCF服务契约的相关介绍。
【编辑推荐】