承载 Service Host 和使用 WCF 服务
作者:作者不详  发布日期:2011/06/12 13:20:37
承载 Service Host 和使用 WCF 服务


承载 Service Host 和使用 WCF 服务

Chris Peiris(澳大利亚 Avanade 公司,http://www.chrispeiris.com/
Dennis Mulder(荷兰 Avanade 公司,http://www.dennismulder.net/



适用于:

• Microsoft .NET Framework 3.0
• Windows Vista/Win7
• Microsoft Internet 信息服务
• Microsoft Visual Studio 2005



摘要:本文讨论 Windows Communication Foundation (WCF) 承载方案和 WCF 服务的使用。传统的 ASMX Web 服务通常仅由 Microsoft Internet 信息服务 (IIS) 承载。在 Microsoft .NET Framework 3.0 中,WCF 服务的承载方案得到了极大的增强。我们将讨论如何将承载模型扩展为包括 Windows 服务和自承载方案。此外,我们还将详细探讨可用于 WCF 服务的 IIS 承载(版本 5.1、6.0 和 7.0)和 Windows 激活服务 (WAS) 承载方案。本文内容是根据 Apress 出版的《Pro WCF: Practical Microsoft SOA Implementation》一书第 5 章内容编撰的。这本书是由 Avanade 公司的全球顾问团队编写的。其主要针对入门级到中级读者。包括这本书在内,Apress 已出版了一系列有关 Windows Presentation Foundation (WPF)、Windows Communication Foundation (WCF) 和 Windows Workflow Foundation (WF) 的丛书。


简介

如果企业依赖于面向服务的体系结构,就必须确保服务能够正常可靠的运行。应用程序可靠性背后最重要的动因是在哪里托管服务以及如何托管服务。在考虑托管服务时,您必须事先考虑几个问题:服务有哪些可用性方面的要求?如何管理和部署服务?是否需要提供对旧版本服务的支持?


了解如何满足这些业务要求对于开发成功的服务是至关重要的。在第 3 章中您将了解到,必须自己提供宿主来承载服务。Windows Communication Foundation (WCF) 本身没有附带宿主,而是提供了一个被称为 ServiceHost 的类,该类允许您在自己的应用程序中承载 WCF 服务。您不必考虑任何网络传输方面的细节,即可确保服务能够被访问。只需以编程方式或声明方式对服务的端点进行配置,然后调用 ServiceHost 的 Open 方法即可。ServiceHostBase 和 ServiceHost 中集成了第 3 章要介绍的有关绑定、通道、调度程序和侦听器的所有一般功能。这意味着用于承载服务的应用程序(运行 ServiceHost 的应用程序)的负载将远远低于您之前预期的水平。


本章讨论何种类型的应用程序可以为 ServiceHost 提供宿主环境。此外,您还会对使用不同应用程序内承载的服务时存在的差异有所了解。


读完本章后,您将学到以下知识:


• 适用于您的各种不同的承载方案
 
• 每种承载方案有哪些优点和缺点
 
• 根据具体情况选择承载方案的指导
 
• 有关 Microsoft 如何实现不同承载方案以及每种方案在哪些方面具有可扩展性的体系结构方面的指导
 



研究承载方案


在 Microsoft .NET 平台上,使用 Microsoft Visual Studio.NET 可以创建几种不同类型的托管 Windows 应用程序:

• WinForms 应用程序
 
• 控制台应用程序
 
• Windows 服务
 
• 承载于 Internet 信息服务 (IIS) 中的 Web 应用程序 (ASP.NET)
 
• IIS 7.0 内提供的 WCF 服务以及 Windows Vista 或 Windows Server 2007 中的 WAS
 

如果您仔细研究 Microsoft Visual Studio 2005 附带的项目模板,就会发现还有其他可选方案供您使用。很显然,我们认为没有其他模板可以在服务世界中用作可行的方案。但值得注意的是,只要 WCF 能够提供 .NET 应用程序域,您就可以在其他任何类型的应用程序中运行服务。(如果您不了解 .NET 应用程序域的原理,请参考下面“了解 .NET 应用程序域”一节的有关内容。)实际上这完全取决于您对宿主的要求。总结这些可选方案,我们主要考虑以下三类常见的 WCF 服务宿主:


• 在托管的 .NET 应用程序中进行自承载
 
• 在 Windows 服务中进行承载
 
• 在不同版本的 IIS 中进行承载
 



可想而知,如本节之前提到的,所有这些宿主在 Visual Studio 中都有相关联的项目模板,并且都有自己的特征。要想更好地了解在每种情况下哪种宿主是最佳选择,必须了解宿主通常的要求和功能。理解这一点后,我们将分别详细介绍每种承载方案。


了解 .NET 应用程序域

如果您了解 Windows 进程的角色以及如何通过托管代码与它们交互,那么您肯定会对 .NET 应用程序域的概念有所了解。要在进程中运行托管 .NET 代码,就需要创建程序集。这些程序集并不直接承载于 Windows 进程中。而是由公共语言运行库 (CLR) 在进程中创建称为“应用程序域”的单独逻辑分区来对托管代码进行隔离。单个进程可能会包含多个应用程序域,每个域都会承载封装于程序集内的不同代码片断。这种对传统 Windows 进程的划分方式可以通过 .NET Framework 提供几个好处。


主要好处如下所示:

• 由于不涉及可执行文件或库的概念,应用程序域决定了 .NET 平台的与操作系统无关的特性。
 
• 您可以根据自身需要控制、卸载和加载应用程序域。
 
• 应用程序域在应用程序或多个应用程序域共生的进程中起到隔离的作用。进程中的应用程序域彼此相互独立,虽然一个域出现故障,但其他域仍可正常工作。
 

承载环境特征


.NET 应用程序需要一个作为宿主的 Windows 进程。该 Windows 进程内部可以承载多个 .NET 应用程序域。应用程序域是 .NET CLR 将托管代码与 Windows 进行隔离所采用的一种手段。CLR 会在每个工作进程中进行初始化,并自动创建一个默认的应用程序域。该默认应用程序域运行于某个进程,并直到该进程结束时才会卸载。默认应用程序域的关闭是由 CLR 来控制的。在大多数宿主中,默认应用程序域内部并不运行任何代码。而是由宿主(或“进程”)来新建应用程序域,以便应用程序域可以独立于进程而关闭。在很多应用程序中,理想的情况是客户端代码和服务器端代码分别在不同应用程序域中执行。通常这种要求是出于安全性和隔离等原因的考虑。


进程和应用程序域之间的关系类似于应用程序和应用程序域与 ServiceHostWCF 之间的关系。如图 5-1 所示,每个进程都至少有一个应用程序域,并且每个应用程序域都可以承载零个或更多的 WCF ServiceHost 实例。WCF 需要一个 Windows 进程内部至少要承载一个应用程序域。


贴图图片

进程、应用程序域和 WCF ServiceHost 关系


注意 尽管可以实例化多个 ServiceHost 实例,但每个应用程序域内保留一个 ServiceHost 实例更便于操作。您可以在一个宿主内使用多个端点公开多个服务接口。更高级的宿主(例如,IIS 和 WAS)确实可以实例化多个 ServiceHost 实例,以提供隔离和不同的安全上下文。


因此,宿主的主要任务是向 WCF ServiceHost 提供 Windows 工作进程和应用程序域。此外,WCF 依赖于应用程序域提供的安全和配置功能。Windows 进程始终使用默认标识运行,WCF 服务可随时使用这个现成的标识。但是,WCF 提供了几个级别的模拟用户的功能(详见本书第 7 章)。如果您不使用这些功能,则由运行服务的 Windows 进程提供安全上下文。前面几章提到过,默认情况下 WCF 依赖于 .NET Framework 中的配置功能,您可以通过应用程序域对其进行访问。


某些宿主还具有管理所运行的应用程序的其他功能。最为突出的是,IIS 还具备自动进程回收、资源限制、日志记录、运行状况指示器等其他功能。您可以通过整个章节的学习了解有关这些主题的详细内容。(不同 IIS 版本具有受 WCF 支持的不同的可管理性功能。最为明显的,Windows XP 中的 IIS 5.1 在管理用户界面方面就受到一些限制。)



承载环境特征


Microsoft 在确保服务开发人员无需过分考虑承载环境方面所做的努力是值得肯定的。ServiceHost 排除了所有技术性的难点,使您可以重点关注服务逻辑,而不必过多地考虑如何承载服务。您必须根据自己的具体要求选择一个宿主。WCF 主要是作为编程模型而编写的,其主要设计目的之一是为了实现“宿主的不可知”。ServiceHost 不关心自身在哪里被实例化,只要您希望服务可被访问时它正在运行即可。也就是说,它需要一个运行 .NET 应用程序域的进程。


在选择应用程序类型时,必须考虑某些特定要求(例如,程序属于控制台应用程序还是 WinForms 应用程序等)。ServiceHost 必须被实例化才能提供运行服务所需的承载环境。典型的 .NET 应用程序(例如,控制台应用程序和 WinForms 应用程序)通常运行在用户桌面计算机上。这些环境并非始终运行,它们可以承载您的服务,但却并非典型的适用于企业的宿主。我们认为适用于企业的宿主应该能够支持更大规模的面向服务的体系结构,在这种体系结构中,多个系统需要依赖服务所公开的关键业务功能。这些适用于企业的宿主通常能够满足诸如高可用性的要求。因此,我们不能将控制台或 WinForms 应用程序做为适用于企业的宿主。


通常情况下,服务运行在服务器上,并由操作员进行管理和操作。管理服务器的操作员一般不希望在服务器重新启动时手动启动控制台应用程序或 WinForms 应用程序。为了让服务应用程序能够在数据中心运行,对于企业级面向服务的情况来说,唯一可行的方案就是在 IIS 上承载服务,或将其作为一项 Windows 服务。


有时,您需要在用户的桌面计算机上实现进程间通信。在这种情况下,只有当用户使用应用程序时,服务才是活动的。需要进行进程间通信的典型应用程序就是控制台应用程序和 WinForms 应用程序。这些应用程序适合承载这些类型的服务。


要能够确定哪种宿主最适合您的情况,您应当考虑到非功能性要求。一般来讲,非功能性要求规定了应用程序的技术要求,以确保其达到应用程序要求的质量和可维护性。对于 WCF 应用程序来说,非功能性要求实际涉及以下内容:


• 可用性:希望何时能够访问您的服务?
 
• 可靠性:当服务由于某些原因出现中断时会发生什么问题?这将如何影响服务的其他使用者?
 
• 可管理性:是否需要便捷地了解承载 WCF 服务的宿主上所发生的情况?
 
• 版本控制:是否需要提供对旧版本服务的支持?是否知道谁在使用您的服务?
 
• 部署:要采用何种部署模型?是否要通过 Microsoft Installer 进程和 Visual Studio 部署包进行安装,还是使用 xcopy 就可以满足需要?
 
• 状态:服务是无状态的吗?是否需要会话?
 


根据这些非功能性要求,您可以确定哪些宿主是符合您的需求的。为了帮助您做出选择,本章后面的内容将介绍不同的承载环境及其优缺点。


注意 由于对自身的运行环境并不了解,因此 WCF 编程模型总是有可能切换到不同宿主,但这并不意味着您必须更改服务实施。首先,您需要在控制台应用程序中进行自承载,以测试并确定服务的原型。

 

自承载您的服务


承载 WCF 服务最灵活、最便捷的方法就是进行自承载。要能够自承载服务,必须满足两个条件。第一,需要 WCF 运行时;第二,需要可以承载 ServiceHost 的托管 .NET 应用程序。您需要自己动手编写启动和停止宿主的代码。



下面是自承载的优点:

易用性:只需几行代码即可使服务运行。

灵活性:通过 ServiceHost<T> 的 Open() 和 Close() 方法,可以轻松控制服务的生存期。

易调试性:可以使用熟悉的调试方式对自承载环境中承载的 WCF 服务进行调试,而不必连接到单个应用程序来激活服务。

易部署性:通常,部署简单 Windows 应用程序与使用 xcopy 一样容易。您不必在服务器场和类似地方部署复杂的方案,即可部署简单的 Windows 应用程序来充当 WCF ServiceHost。

支持所有绑定和传输:自承载并不限制您仅能使用现有的绑定和传输技术。在 Windows XP 和 Windows Server 2003 上,IIS 限制您只能使用 HTTP。


下面是自承载的缺点:

可用性受到限制:服务只有在应用程序运行时才能被访问。

功能受到限制:自承载的应用程序在对高可用性、易管理性、可靠性、可恢复性、版本控制和部署方案的支持方面受到一定限制。至少,现有的 WCF 无法提供这些支持,因此在自承载的情况中,您必须自己实现这些功能;例如,默认情况下 IIS 提供了这些功能中几项。


换句话说,对于企业级方案来说不应考虑自承载方式。自承载适用于企业项目的开发或演示阶段。此外,当您希望用户桌面应用程序进行相互通信或在点对点情况下,可以对服务进行自承载。本书第 12 章对此进行了描述。


第 3 章介绍了几个自承载的方案示例,这些示例全都使用简单的控制台应用程序。为了在实际工作环境中更好地说明自承载,本章提供了一个 WinForms 应用程序,该程序所承载的服务用于跟踪 QuickReturns Ltd. 案例研究中证券商发布的报价。


在此方案中,有两个不同的 WinForms 应用程序。一个是证券商管理器应用程序,证券商可以使用该程序发布报价并进行证券交易。另一个程序是单独的 WinForms 应用程序,用于跟踪发布的报价。如列表 5-1 所示,该程序公开一个服务,所公开的服务实现了 ITradeTrackingService 约定,从而实现对报价的跟踪。证券商管理器应用程序会在成功通过 TradeService 发布报价后调用该服务。


列表
5-1. TradeTrackingService 的 ServiceContract

C# Code:

using System.ServiceModel;
using QuickReturns.StockTrading.ExchangeService.DataContracts;

namespace QuickReturns.StockTrading.TradeTrackingService.Contracts
{
   [ServiceContract()]
   interface ITradeTrackingService
   {
      [OperationContract()]
      void PublishQuote(Quote quote);
   }
}


 

在 Windows 服务中进行承载


在 Windows 服务中承载 WCF 服务是一种合理的选择。不应将 Windows 服务与 WCF 服务混为一谈。它们都使用“服务”一词,但却具有不同的含义。Windows 服务是由操作系统管理的进程。Windows 提供了服务控制管理器,用于控制操作系统上安装的服务。Windows 通过服务来支持诸如网络、USB、远程访问、消息队列等操作系统功能。您可以使用 Visual Studio 2005,利用 Windows 服务项目模板(如图 5-2 所示)创建 Windows 服务。




贴图图片

Visual Studio 2005 Windows 服务项目模板



Windows 服务项目模板会生成一个项目,其中包含两个文件:service1.cs 文件和 program.cs 文件。其中 service1.cs 文件包含服务实现,而 program.cs 文件则用于实例化并实质上承载 Windows 服务。要在 Windows 服务内部承载 WCF 服务,只需执行 Windows 服务的 Start() 方法和 Stop() 方法,如列表 5-2 所示。由于启动 Windows 服务的范例与启动 WCF ServiceHost 内的服务相似,因此最后需要将 WCF 服务的生存期与 Windows 服务的生存期相连。


列表
5-2. 承载 WCF ServiceHost 的 Windows 服务


C# Code:

using System;
using System.ServiceModel;
using System.ServiceProcess;
using QuickReturns.StockTrading.ExchangeService;

namespace QuickReturns.StockTrading.ExchangeService.Hosts
{
   public partial class ExchangeWindowsService : ServiceBase
   {
      ServiceHost host;
      
      public ExchangeWindowsService()
      {
         InitializeComponent();
      }
      
      protected override void OnStart(string[] args)
      {
         Type serviceType = typeof(TradeService);
         host = new ServiceHost(serviceType);
         host.Open();
      }
      
      protected override void OnStop()
      {
         if(host != null)
         host.Close();
      }
   }
}



由此可见,编写用于承载 WCF 服务的 Windows 服务非常容易,而且与本章前面的自承载方案相比,它还有几个好处。另一方面,编写承载 WCF 服务的 Windows 服务也有一些您必须了解的缺点。


首先让我们看一下优点:

可以自动启动:Windows 服务控制管理器允许将启动类型设置为自动,从而可以在 Windows 启动立即启动服务,而不必在计算机上进行交互登录。

可以恢复:Windows 服务控制管理器内建了对发生失败后重新启动服务的支持。

安全标识:Windows 服务控制管理器允许您选择运行服务所使用的特定安全标识,包括内置的系统或网络服务帐户。

可管理性:通常情况下,Windows 操作员对那些用于进行 Windows 服务安装和配置的服务控制管理器和其他管理工具都非常熟悉。这将使 Windows 服务在实际工作环境中更容易被采纳;但是,为了保证服务的可维护性,您可能需要添加某些检测和日志记录功能。

支持所有绑定和传输:自承载并不限制您仅能使用现有的绑定和传输技术。在 Windows XP 和 Windows Server 2003 上,IIS 限制您只能使用 HTTP。


接下来是 Windows 服务的一些缺点:

部署: 必须通过 .NET Framework Installutil.exe 实用工具或通过安装包中的自定义操作来安装服务。

功能受到限制:Windows 服务在对高可用性、易管理性、版本控制和部署方案的支持方面同样也受到一定限制。实际上,您必须自己编写自定义代码来满足这些要求,而 IIS 在默认情况下就带有这些功能的其中几项。Windows 服务确实添加了可恢复性和一些安全功能,但有些任务仍然需要您亲手去做。


要能够在服务控制管理器中安装服务,必须在项目中添加安装程序。Visual Studio 2005 允许您方便地完成该操作:


1.

在 Windows 服务项目中打开 Service 类的设计器视图。

2.

单击设计器背景以选择服务本身,而并非其任何内容。

3.

在“属性”窗口中,单击属性列表下灰色区域中的“添加安装程序”链接,如图 5-3 所示。默认情况下,该操作将在项目中添加一个包含两个安装程序的组件类。组件名为 ProjectInstaller,它包含的安装程序是服务的安装程序和该服务相关进程的安装程序。


贴图图片

Windows 服务项目的“添加安装程序”功能


4.

访问 ProjectInstaller 的设计器视图,并单击 ServiceInstaller1。

5.

在“属性”窗口中,将“ServiceName”属性设置为“QuickReturns Exchange 服务”。

6.

将“StartType”属性设置为“自动”,如图 5-4 所示。


.

图 5-4. QuickReturns Exchange 服务的属性窗口

7.

访问 ProjectInstaller 的设计器视图,并单击“serviceProcessInstaller1”。

8.

在“属性”窗口中,将“帐户”属性设置为“网络服务”,如图 5-5 所示。


.

图 5-5. QuickReturns Exchange 服务的属性窗口

为了能够创建可用于安装 Windows 服务的安装程序,必须向解决方案添加 Visual Studio 安装程序和部署项目。以下步骤描述了如何向解决方案添加安装程序和部署项目:

1.

选择“文件” | “添加” | “新建项目”。

2.

在“新建项目”对话框中,选择“其他项目类型”类别,选择“安装和部署”,然后选择“安装项目”,如图 5-6 所示。

.

图 5-6. Visual Studio 2005 安装项目模板

3.

在解决方案资源管理器中,右键单击安装项目,指向“添加”,然后选择“项目输出”,如图 5-7 所示。此时将显示“添加项目输出组”对话框。


.

图 5-7. 添加 Windows 服务项目输出

4.

选择 Windows 服务项目。

5.

从列表框中,选择“主输出”,然后单击“确定”。


此操作将向安装项目添加 Windows 服务的主输出的项目项。现在,添加用于安装可执行文件的自定义操作。若要向安装项目添加自定义操作,请执行以下步骤:



1.

在解决方案资源管理器中,右键单击安装项目,指向“视图”,然后选择“自定义操作”,如图 5-8 所示。此时将显示“自定义操作”视图。

.

图 5-8. 打开“自定义操作”视图

2.

右键单击“自定义操作”,选择“添加自定义操作”。

3.

双击列表框中的应用程序文件夹将它打开,从 Windows 服务项目中选择“主输出”,然后单击“确定”。主输出将添加到自定义操作的所有四个节点中:安装、提交、回滚和卸载。

4.

生成安装项目。


编译项目时,输出的是 Microsoft 安装程序文件 (.msi) ,通过该文件可以将服务安装到 Windows 服务控制管理器中。


注意
本章介绍生成 Windows 服务和 Windows 服务安装程序的基础知识。如果将 Windows 服务设置为在不受限制的 Localsystem 帐户下运行或基本合适的网络服务帐户下运行,就安全最佳方法而言,这并非最佳选择。通常,操作员能够在安装期间选择凭据,或在安装之后通过服务控制管理器管理控制台管理单元(可以通过 Windows 计算机管理进行访问)来调整安全标识设置。有关开发 Windows 服务的详细信息和最佳方法,请参阅本书第 7 章、MSDN 帮助或 .NET 开发专著。


 

使用 WCF 服务


在前一节中,我们介绍了不同的承载方案。而所选的承载方案会影响使用者端。使用 WCF 服务可以有多种方式。如果客户端正在使用 WCF,则生产效率将非常高,因为 WCF 附带的工具可以生成用于调用 WCF 服务的代理类。WCF 主要通过 SvcUtil.exe 来提供标准和工具支持,SvcUtil.exe 将作为主要的元数据解释工具。它与 WCF Framework 利用反射询问具有合适属性的类型这一功能结合在一起,使生成和使用 WCF Framework 与现有框架相比,复杂性更低。此外,Visual Studio 2005 带有易用的功能,可以向项目添加服务引用,并可无缝地自动生成代理类。


实际上,您可以有以下选择:

从服务检索 WSDL,并手动制作代理来调用服务。这是客户端没有 WCF 时的典型方案。关于此方案,请参考第 13 章。

使用 Visual Studio 2005 的“添加服务引用”功能,并让它生成要在客户端上使用的代理。

使用 SvcUtil.exe 工具生成代理类。


在下面几节中,我们将介绍后面两个选项:Visual Studio 2005 和 SvcUtil.exe。

 

服务代理


服务代理使您能够以面向对象的方式使用服务。代理类对服务所使用的通信模型进行抽象,这样,客户端开发人员不会直接意识到他正在与(远程)服务对话。这就像在调用本地代码一样。代理类可实现服务的服务接口,从而使您能够调用服务接口上的方法,就好像它们是本地方法。代理是为服务接口中使用的任何自定义类型而生成的。列表 5-11 包含 QuickReturns Ltd. 示例中为 TradeService 服务生成的代理的片段。它演示了在客户端有一个可用 Quote 映射到服务器端上的 Quote 对象,尽管它们是不同的类。Quote 对象按照合同进行序列化,以便它在服务端可以序列化为服务端版本的 Quote 数据合同。此外,可以看到 GetQuote 和 PlaceQuote 方法调用一个基类,而该基类最后将以所配置的传输方式跨服务边界进行调用。


列表 5-11. 为 TradeService 服务生成的示例代理


C# Code:

namespace SimpleClientWithProxy.ExchangeService
{
   [DataContract()]
   public partial class Quote : object, IExtensibleDataObject
   {
      // 省略了打印代码中的 Quote 数据成员,见示例代码
   }
}

[GeneratedCode("System.ServiceModel", "3.0.0.0")]
[ServiceContract()]
public interface ITradeService
{
   [
   OperationContract(Action =
   "http://tempuri.org/ITradeService/GetQuote",
   ReplyAction =
   "http://tempuri.org/ITradeService/GetQuoteResponse")]
   Quote GetQuote(string ticker);
   
   [
   OperationContract(Action =
   "http://tempuri.org/ITradeService/PublishQuote",
   ReplyAction =
   "http://tempuri.org/ITradeService/PublishQuoteResponse")]
   void PublishQuote(Quote quote);
}

[GeneratedCode("System.ServiceModel", "3.0.0.0")]
public interface ITradeServiceChannel : ITradeService, IClientChannel
{
}

[GeneratedCode("System.ServiceModel", "3.0.0.0")]
public partial class TradeServiceClient : ClientBase<ITradeService>,
ITradeService
{
   // 省略了打印代码中的一些构造函数,见示例代码
   
   public SimpleClientWithProxy.ExchangeService.Quote
   GetQuote(string ticker)
   {
      return base.Channel.GetQuote(ticker);
   }
   
   public void PublishQuote(
   SimpleClientWithProxy.ExchangeService.Quote quote)
   {
      base.Channel.PublishQuote(quote);
   }
}



 

使用 Visual Studio 2005


与创建 ASP.NET 代理相似,如果在 IDE 中右键单击项目,可以看到三个用于添加引用的选项,如图 5-18 所示。

.

图 5-18. 添加对 WCF 服务的引用


您要查找的选项是“添加服务引用”。此菜单选项是 SvcUtil.exe 实用程序周围的包装(下一节将对此进行介绍),它实际上将产生具有所需参数的进程。一旦选择了“添加服务引用”,就将看到在图 5-19 中显示的对话框。

.

图 5-19. “添加服务引用”对话框


一旦在对话框中单击“确定”,该加载项将产生 SvcUtil.exe,并生成需要的代理类和必需的配置文件(或修改它),并将所需引用添加到项目中。现在,项目的引用将列出 WCF 程序集。


注意
要使该操作有效,必须运行 Windows ServiceHost,或更改 URL 以指向 IIS 中承载的任何服务(使 URL 指向任何 .svc 文件)。


现在,即可开始在服务层中安排第一个服务调用。示例解决方案文件按以下方式进行了修改,以帮助您查看代码:

解决方案上的“设置启动项目”已选中多个项目。

ExchangeServiceIISHost Web 项目的“使用动态端口”已设置为 False,并且“端口号”使用硬编码设置。

需要将对象的简短说明添加到项目中。在 SvcUtil.exe(“添加服务引用”)调用期间,在项目中自动添加了下面的项和引用。其中一些只是为了帮助 Visual Studio 集成;其他则是通过代理直接使用服务所必需的。



服务引用:在此文件夹中,我们添加了两项。第一,“映射”文件为通过 Visual Studio 加载项生成和重新生成代理提供支持。第二,ExchangeService.cs 代表具体的代理类实现,它利用命名空间 System.ServiceModel 提供简单的集成类。

配置:第二项是 App.config 文件。App.config 文件(在 Visual Studio 构建过程中将自动重命名为“<程序集名称>.config”)提供运行时 WCF 配置参数。如果看一看此文件的内部,将发现大量设置,其中很多是默认的或多余的。常见做法是,在生成该文件后使用 WCF SvcConfigEditor.exe 编辑器实用程序管理该文件。此实用程序位于 Windows SDK Bin 目录下。还可以在“Visual Studio 2005 工具”菜单中找到它。图 5-20 显示了该工具的实现。

.

图 5-20. SvcConfigEditor.exe


从图 5-20 中的“SvcConfigEditor.exe”屏幕上可以看到,通过配置可以管理数量巨大的详细属性。这是 WCF 的最强大的优势之一:能够对具体实现的很多方面进行控制,而不会影响核心服务实现。服务实现不需要更改即可从基于 HTTP 的协议迁移到另一个面向消息的协议这一概念就是一个示例。若要获得有关该工具的功能的详细信息,请参考本书的第 3 章、第 6 章或 MSDN 帮助。

命令行实现


一种替代方法是直接利用 SvcUtil.exe 实用程序,而不是 Visual Studio 加载项。在从 Visual Studio 中直接执行时,Visual Studio 加载项将再次带参数调用 SvcUtil.exe 以生成代理。通过查看“输出”窗口,并在下拉列表中将“显示输出”设置为“服务引用”,可以看到命令行和该命令的结果。


若要手动生成,可通过选择“开始” | “所有程序” | “Microsoft Windows SDK” | “CMD”,以选择 CMD 窗口。此命令提示符很有用,因为它的路径被设置为 SDK 工具和实用工具所在的二进制目录。


您将使用 SvcUtil.exe 命令行工具生成可在 SimpleClientWithProxy 项目中使用的两个输出。但是,本章附带的示例代码使用了上一节介绍的“添加服务引用”方法。此处介绍的步骤解释了如何生成与“添加服务引用”相同的输出。它生成的输出文件是客户端代理源代码文件和应用程序配置文件。然后,这些文件将合并到客户端项目中。SvcUtil.exe 可以生成这二者。在此示例中,以下命令(它只有一行,尽管此处显示多行)将产生代理类和配置文件:


列表
5-12. 用于产生代理类和配置文件的命令



svcutil /config:app.config /out:"ExchangeService.cs" /language:csharp 
/n:*,
SimpleClientWithProxy.ExchangeService 
"http://localhost/ExchangeService/?
ExchangeService.svc"




警告
要让此操作有效,需要一个正在运行的 Windows ServiceHost 版本,或者必须更改 URL 以指向 IIS 中承载的任何服务(使 URL 指向本章讨论的任何 .svc 文件)。此外,服务需要 metadataexchange 端点,第 3 章对此进行了介绍。本章附带的代码配置了 metadataexchange 端点,但在本章中它不在内嵌代码内!


命令有很好的自解释功能。/n 开关表明生成的代理类应当属于哪个命名空间。最后一个参数是可以在其上找到架构信息的服务端点的 URL。注意,?wsdl 可以替换为 ?mex,因为 SvcUtil.exe 同时支持两种发现方法。通过从命令提示符执行 svcutil.exe /?,可以获得进一步帮助。


下一步是获得输出文件 ExchangeService.cs 和 App.config,并将它们合并到项目中。通过从 Visual Studio 2005 中的“项目”菜单选择“添加现有项”,可以将第一个文件 ExchangeService.cs 直接添加到项目中。


第二个文件必须作为应用程序配置 (App.config) 文件添加到项目中。如果项目还没有 App.config 文件,则可以从“项目”菜单中再次选择“添加现有项”以添加该文件。如果已有现成的 App.config,则必须合并 system.serviceModel 部分,以确保具备所有适当的子元素。

结论

在了解了有关承载的可选方案的所有内容后,您将能够构建 WCF 应用程序,并在任何需要的地方承载它们。此外,您还能够解释在最新可用环境(Windows Vista 或 Windows Server 2007 上的 IIS 7.0 与 WAS)中进行承载的好处。


原文:http://www.microsoft.com/china/MSDN/library/Windev/WindowsVista/bb332338.mspx?mfr=true




C/S框架网|原创精神.创造价值.打造精品


扫一扫加作者微信
C/S框架网作者微信 C/S框架网|原创作品.质量保障.竭诚为您服务

上一篇 下一篇