一个WCF服务可以在操作系统中运行的任何托管进程中寄宿。服务本身一般并不知道或者关心它是怎么被寄宿的,尽管它可以通过丰富的APIs来找出来。它可以寄宿到一个不被注意的随机器初始化时启动随机器关闭时关掉的Windows 服务上,或者在一个最小化到Windows系统托盘的客户端应用程序。最普通的用法,就是在IIS里托管一个WCF服务。
讨论
IIS非常合适作为宿主。IIS是Windows的一部分而且有一个重要的已经发布的关于管理,安全和开发应用的知识库。IIS是可扩展的,可信赖的而且是非常安全的。所以IIS有非常出色的条件来作为宿主。基于IIS的ASMX是WCF之前的最广泛适用的用来发布网络服务的技术,WCF继承了这个基础。在.NET 3.5 中,作为在IIS发布网络服务的推荐方式,ASMX已经被WCF取代。
IIS非常合适作为宿主。IIS是Windows的一部分而且有一个重要的已经发布的关于管理,安全和开发应用的知识库。IIS是可扩展的,可信赖的而且是非常安全的。所以IIS有非常出色的条件来作为宿主。基于IIS的ASMX是WCF之前的最广泛适用的用来发布网络服务的技术,WCF继承了这个基础。在.NET 3.5 中,作为在IIS发布网络服务的推荐方式,ASMX已经被WCF取代。
还有,要记住WCF的ABCs:地址,绑定和契约。当以IIS作为宿主时,服务的地址是由包含服务文件的虚拟目录决定的。因为IIS可以解析HTTP/S协议,所以绑定也总是使用这两个协议,basicHttpBinding和wsHttpBinding因此可以使用。这是仅有的两个系统自定义的可以使用的绑定。任何借助HTTP协议的绑定都可以使用IIS寄宿。服务终结点的SOAP定义契约,不受制于IIS寄宿服务的现实,所以没有特别的契约是为了符合IIS寄宿的。
与ASMX类似,WSDL格式的元数据,可以通过输入以WSDL为参数的服务地址然后从IIS寄宿服务中获取(http://localhost/myservice.svc?wsdl)。当IIS接收到请求时,它调用服务的MEX终结点然后返回WSDL格式的结果。与ASMX不同的是,MEX终结点默认情况下不被暴露出来,所以它不会对从Visual Studio 2008添加服务引用或者使用svcutil.exe的元数据请求进行回复。你必须明确的使用代码(列表1.4)或配置文件(列表1.5)使能MEX终结点。
三步寄宿IIS服务
在IIS中寄宿一个服务有三步:
在IIS中创建一个虚拟应用来存储服务。
创建一个SVC文件来定义服务实现。
增加web.config文件来包括<system.serviceModel>部分
在IIS中寄宿一个服务有三步:
在IIS中创建一个虚拟应用来存储服务。
创建一个SVC文件来定义服务实现。
增加web.config文件来包括<system.serviceModel>部分
定义一个IIS虚拟应用
IIS中的虚拟应用与一个应用程序池和虚拟目录关联。对WCF来说,应用程序池创建ServiceHost而虚拟目录存储服务文件(SVC,config,.dll).
IIS中的虚拟应用与一个应用程序池和虚拟目录关联。对WCF来说,应用程序池创建ServiceHost而虚拟目录存储服务文件(SVC,config,.dll).
创建一个SVC文件
SVC文件引用服务实现。SVC文件可以使用文本编辑器或者Visual Studio 创建。大多数情况下,实现的类会存在一个dll 中并会被SVC文件引用。DLL必须存在于虚拟目录下的bin目录或者GAC中。1.10 列表侠士了引用了一个编译的.NET类的SVC文件。
另外,SVC文件可以包含具体实现。在那种情况下,SVC文件将会很长,但是将会有很少的外部依赖。因为源代码在寄宿服务的IIS服务器上,源代码可以被一个操作或者支持组修改而不用访问开发环境并编译DLL。这有显而易见的风险和好处。风险包括容易在知识产权和变更管理上失去控制,因为代码在每台网络服务器上都是可见和可更新的。而且,性能将会因为这种方法而受到影响。好处包括代码的透明度和漏洞修复,因为客户清楚的知道代码做了什么和在必要的情况下应该如何修改。列表1.11 显示包含一个服务实现的SVC文件。这个代码即那个会在它第一次被调用时编译。
SVC文件引用服务实现。SVC文件可以使用文本编辑器或者Visual Studio 创建。大多数情况下,实现的类会存在一个dll 中并会被SVC文件引用。DLL必须存在于虚拟目录下的bin目录或者GAC中。1.10 列表侠士了引用了一个编译的.NET类的SVC文件。
另外,SVC文件可以包含具体实现。在那种情况下,SVC文件将会很长,但是将会有很少的外部依赖。因为源代码在寄宿服务的IIS服务器上,源代码可以被一个操作或者支持组修改而不用访问开发环境并编译DLL。这有显而易见的风险和好处。风险包括容易在知识产权和变更管理上失去控制,因为代码在每台网络服务器上都是可见和可更新的。而且,性能将会因为这种方法而受到影响。好处包括代码的透明度和漏洞修复,因为客户清楚的知道代码做了什么和在必要的情况下应该如何修改。列表1.11 显示包含一个服务实现的SVC文件。这个代码即那个会在它第一次被调用时编译。
列表1.11 包含内嵌实现的SVC文件
%@ServiceHost Language=c# Service="EssentialWCF.StockService"
using System; using System.ServiceModel; using System.ServiceModel.Description; namespace EssentialWCF { [ServiceContract] public interface IStockService { [OperationContract] double GetPrice(string ticker); } public class StockService : IStockService { public double GetPrice(string ticker) { return 94.85; } } }
在web.config中实现<system.serviceModel>
因为IIS在寄宿服务,服务终结点定义必须在配置文件中而不是在代码中定义。配置信息存储在web.config 中,在<system.serviceModel>节点下。和其他寄宿模型一样,终结点必须包含ABCs:地址,绑定和契约。列表1.12显示了在寄宿服务的IIS内部的web.config 文件。注意<system.serviceModel>节点和列表1.5的一样。
服务地址由SVC文件存储的虚拟目录的地址决定。如果仅有一个终结点在服务中被定义,那么终结点地址可以是空的,这表明终结点地址和服务地址一样。如果一个服务中有多个终结点,那么每个终结点可以有一个相对地址。
绑定必须使用一个使用HTTP协议来传输的信道栈。WCF自带两个信道,basicHttpBinding和wsHttpBinding.自定义绑定,信道栈的组成与内建的实现方式不同的也支持,只要它们使用HTTP作为传输协议。自定义绑定将会在第三章和第四章详细介绍。
终结点契约定义服务中类的实现。运行时代码对服务来说是可以访问的,或者在/bin 目录,或者在GAC中,或者嵌入到SVC文件中。
列表1.12 在web.config 中定义服务
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="EssentialWCF.StockService" behaviorConfiguration="myServiceBehavior"> <endpoint address="" binding="basicHttpBinding" contract="EssentialWCF.IStockService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="myServiceBehavior"> <serviceMetadata httpGetEnabled="True" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>