设计服务接口
如果把业务功能作为一个服务暴露,需要为客户端调用提供一个入口点,这个入口点抽象了内部实现。也可以使用不同的认证要求和服务层面协定(SLA)委托为不同的调用者暴露相似的功能。通过创建一个服务接口提供一个入口点到服务。
一个服务接口是一个软件实体的作为外观的典型实现,处理映射和转换服务来允许和服务的通讯,强迫执行通讯的一个处理和一个策略。服务接口暴露方法,可以被个别调用,或者在一个指定顺序来构成实现一个业务任务的会话。例如,在零售应用程序场景中的信用卡服务可以提供一个名叫AuthorizeCard的服务,来验证信用卡明细,第二个名叫ProcessPayment的方法来从卡持有者的账户中转移资金到零售商。这些步骤的执行将用合适的序列处理订单支付。
必需的通讯格式、数据架构、安全需求和过程作为标准的一部分被确定,是通过服务发布。这个契约提供客户端和服务接口的定位和通讯的信息。
当设计服务接口时,考虑下面的建议:
l 服务接口被作为应用程序的可信赖的边界考虑。
l 如果服务接口被暴露给外部的组织和客户,或者对公共是有效的,把它们设计为这样一种方式---改变内部实现而不需要改变服务接口。
l 服务中的相同逻辑可以被不同客户端的不同方法所消费,所以有必要为相同的功能发布多个服务接口。
l 不同服务接口可以定义在不同的通讯通道,消息格式,认证机制,执行服务层面的协定,和事务能力。公共服务层面的协定被实时定义到对伴随着某些数量信息的某些请求的响应。
用不同的方法实现服务接口,依赖于想暴露应用程序和服务的功能的方式:
l 用XML Web 服务暴露业务逻辑,可以使用ASP.NET Web服务页面或者暴露一些通过使用SOAP和HTTP的DotNET远程的组件。
l 暴露服务功能,可以发送给消息队列的消息的客户端,可以使用消息队列触发器,或者Enterprise Service队列组件,或者可以写自己的‘消息接受‘服务。
更多信息,见第三章(安全,运行管理和通讯策略)的“设计通讯策略“部分。
服务接口特征
考虑下面的服务接口的设计特征:
l 有时,DotNET基础结构会允许你使用透明服务接口(例如,暴露Enterprise Service对象在Windows DotNET服务里作为Web服务),有时需要增加特定的工件到应用程序,诸如,XML Web服务,BizTalk 编排工作流,或者消息端口。考虑好使用透明服务接口的冲突,因为他们不可能提供抽象必须适应对业务功能的稍后的改变,而不影响服务接口。实现的层面有它的开发成本,但会帮助隔离变化和造成应用程序更多的可维护性。
l 服务接口可以实现缓存,映射,简单格式和架构的转换;然而,这些层面不实现业务逻辑。
l 服务接口可以包括一个事务的传送(例如,消息队列),或者一个非事务传送(例如,HTTP上的XML Web 服务)。这个会影响错误和事务管理策略。
l 设计和其它平台和服务的最大化的协作能力,依赖任何可能的行业标准(通讯、安全、格式,标准或者简单的消息格式,例如,对于XML Web服务的简单XML架构),和非特定平台的认证机制。
l 有时,服务接口有它拥有的安全识别身份,会审核进入的消息,但不能够模拟它们。当调用部署在不同服务器的业务组件时,将要考虑使用这个方法。
用服务接口使用业务外观
用于暴露业务逻辑服务的通道和通讯机制与实现服务接口的代码有关联的途径。例如,如果选择构建Web服务,服务接口的大部分逻辑将归宿在名字叫asmx.cs文件中。也可以通过消息队列暴露服务,这情况下,可以使用来自Enterprise Service、自定义监听器,或者消息队列触发器的队列化组件,“激活”承当服务接口的组件。
如果计划构建可以被不同的机制来调用的系统,需要在业务逻辑和服务接口直接增加一个外观层。到实现这个外观时,把策略相关的代码合并在一个地方(诸如,认证,审核,验证等等),方便用多种通道处理的多个服务接口之间重用。因为这个外观隔离业务组件实现通信机制的变化,所以它提供特别好的可维护性。因而,服务接口代码仅处理通讯机制和通道的明细(例如,检查来自消息队列消息的web 服务SOAP头和Getting信息),为调用业务外观组件而设置正确的内容。图2.10显示了使用这个风格的业务外观。
图2.10 为服务接口使用业务外观
图2.10展现一个例子,业务外观如何用于系统的业务接口。IIS和ASP.NET接收HTTP调用(1)和一个名字叫MyWebService.asmx的Web服务接口(2)。这个服务接口检查一下SOAP消息头信息,设置基于Web服务认证的正确的首要对象。然后,调用一个业务外观组件(3)验证,认证和审核调用。再而,外观调用一个业务组件来执行业务工作(4)。后来,系统需要一个消息队列的支持,所以,一个自定义监控器被构建,用来捡起消息和调用名字叫MyMSMQWorker的服务接口组件(6)。这个服务接口组件抽取了消息队列消息属性(诸如,消息体,消息标签等等)数据,使这些数据脱离消息队列消息,在基于消息队列消息签名中,设置正确的首要对象。接着,调用业务外观。通过分解业务外观代码在服务接口的外部,应用程序能够使用更少的努力增加通讯机制。
服务接口里的事务处理
服务接口需要提供一个提供的事务处理的能力的通道(如,消息队列),或者不需要(如,XML Web服务)。设计事务处理边界是很重要的,这样的操作可以在面对错误时进行重新尝试。如此做,确保使用的所有资源是具有事务性的,标记“请求事务”的根组件,标记所有子组件作为“请求事务”或者“支持事务”。
伴随着事务性的消息机制,服务接口首先启动事务,然后捡起消息。如果事务回滚,消息被自动“不接受”,且被放置到重新尝试的队列中。当使用消息队列,Enterprise Service队列组件,或者消息队列触发器时,可以定义一个消息为排队—接受操作,为达到事务性的自动化。
如果使用没有事务的消息机制(如,XML Web服务),一定从服务接口的代码里调用事务的根。在失败的情况下,可以设计服务接口代码来重试这个操作,或者返回给调用者一个合适的异常,或者调整数据表现一个失败。