WCF分布式开发步步为赢系列的(6):WCF服务契约继承与分解设计
[2] 服务契约继承
[3] 服务契约分解概念
[4] 服务契约分解代码分析
【2】服务契约继承:
服务契约的定义和接口定义类似,接口可以继承与多个接口。但是WCF契约属性是不支持继承的。由于WCF框架自身的问题,不支持契约属性的继承,因此这给我们服务契约属性的声明和使用却有不少限制。在使用契约继承属性的过程中腰注意服务端契约的属性继承问题,此外就是客户端添加服务引用后,无法还原服务端契约层级的关系,所有的操作契约由一个契约类封装。因此实际编程我们要兼顾到两个方面的情况。
【2.1】服务端契约层级:
接口支持继承。但ServiceContract特性不支持继承的,我们查看其实现代码可以知道Inherited = false,即不支持继承,部分代码如下:
false, AllowMultiple = false)]
public sealed class ServiceContractAttribute : Attribute
{
}
因此在定义多层服务契约接口的时候,我们必须在每层接口上标记ServiceContract属性,以支持WCF服务契约属性。
示例代码如下:
[ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
interface IVehicle
{
}
//接口继承关系不支持ServiceContract继承
[ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
interface ITruck : IVehicle
{
}
货车服务类能够实现整个WCF契约层级接口,我们这里实现了Run跑和Carry运输货物的契约,代码如下:
public class WCFServiceTruck : ITruck
{
//实现接口定义的方法
public string Run()
{
Console.WriteLine("Hello! ,This an inherite demo");
return "Hello! Truck is running ";
}
//实现接口定义的方法
public string Carry()
{
Console.WriteLine("Hello! ,This an inherite demo");
return "Hello! Truck is carrying ";
}
}
宿主可以为契约层级最底层的接口公开一个单独的终结点,配置文件设置代码如下:
WCFService.WCFServiceTruck">
<endpoint
address="http://localhost:9003/WCFServiceTruck"
binding="wsHttpBinding"
contract="WCFService.ITruck">
endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExc
hange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:9003/"/>
baseAddresses>
host>
service>
【2.2】客户端契约层级:
客户端添加服务端数据引用,导入一个服务终结点的元数据时,反序列化生成的客户端契约将不再维持原来的层级关系。一个单独的契约,名称为终结点公布的契约名。含了层级中继承相关所有接口定义的操作契约。OperationContract特性中的Action与ResponseAction属性,可以保留原来定义每个操作的契约名。我们要想恢复服务端契约继承的层级关系,客户端可以手工修改代理以及导入契约的定义,恢复契约层级。手动恢复方式其实带给我们很多灵活性,但是也增加了工作量和复杂度。实际项目里一般接触不多,这里就不详细介绍,需要的话可以查阅相关的资料。