技术开发 频道

Programming WCF Services:操作重载与契约层级

    服务契约的分解与设计

    契约分离与接口隔离原则(ISP,Interface Segregation Principle)的基本精神是一致的。ISP原则建议使用多个专门的接口,而不是使用单个接口,这样可以防止接口污染,有利于接口重用。契约分解同样如此,但它还要受到实现契约代价的约束。

    书中提供了服务契约的分解准则。“合理的契约分解可以实现深度特化、松散耦合、精细调整以及契约的重用。这些优势有助于改善整个系统。总的来说,契约分解的目的就是使契约包含的操作尽可能少。”

    设计面向服务的系统时,需要平衡两个影响系统的因素(参见图2-1)。一个是实现服务契约的代价,一个则是将服务契约合并或集成为一个高内聚应用程序的代价。

图2-1 平衡服务的个数与规模

    定义服务契约时,还要注意到书中所谓的准属性操作(Property-Like Operation)的使用。一言以蔽之,就是如果涉及到对对象状态的管理(在C#中一般体现为属性),则这样的操作不宜被公开为服务操作。原因在于:“客户端应该只负责调用操作,而由服务去管理服务对象的状态。”

    契约查询

    要查询契约,首先需要了解元数据的信息,WCF提供了如下的几个辅助类,位于System.ServiceModel.Description命名空间:
public enum MetadataExchangeClientMode { MetadataExchange, HttpGet } class MetadataSet : ... {...} public class ServiceEndpointCollection : Collection<ServiceEndpoint> {...} public class MetadataExchangeClient { public MetadataExchangeClient( ); public MetadataExchangeClient(Binding mexBinding); public MetadataExchangeClient(Uri address, MetadataExchangeClientMode mode); public MetadataSet GetMetadata(); public MetadataSet GetMetadata(EndpointAddress address); public MetadataSet GetMetadata(Uri address,MetadataExchangeClientMode mode); //More members } public abstract class MetadataImporter { public abstract ServiceEndpointCollection ImportAllEndpoints( ); //More members } public class WsdlImporter : MetadataImporter { public WsdlImporter(MetadataSet metadata); //More members } public class ServiceEndpoint { public EndpointAddress Address {get;set;} public Binding Binding {get;set;} public ContractDescription Contract {get;} //More members } public class ContractDescription { public string Name {get;set;} public string Namespace {get;set;} //More members }
    书中提供了元数据的查询方法,同时还实现了一个专门用于操作元数据的MetadataHelper类。
public static class MetadataHelper { public static bool QueryContract(string mexAddress,Type contractType); public static bool QueryContract(string mexAddress,string contractNamespace, string contractName); //More members }
    可以为MetadataHelper类提供我们希望查询的契约类型,或者提供该契约的名称与命名空间:
string address = "..."; bool contractSupported = MetadataHelper.QueryContract(address,typeof(IMyContract));
    具体的实现可以参见书中的描述,完整的实现代码可以到作者的网站(http://www.idesign.net)去下载。
0
相关文章