在 _NET 中使用 COM+ 服务

在 .NET 中使用 COM+ 服务


升级到 Microsoft .NET
Tim McCarthy - InterKnowlogy
Paul D. Sheriff - PDSA, Inc.
2002 年 2 月

 

摘要:将新的 Microsoft .NET 组件添加到现有的 COM 和 COM+ 应用程序中,它们将协同工作;如果您需要开发能够参与事务、利用基于角色的安全性或者与队列交互的 .NET 应用程序,这样做对您很有帮助。

目标
  • 学习在 Microsoft® .NET 中使用 COM+ 服务。
  • 创建被服务的组件。
  • 部署被服务的组件。
前提条件

要彻底理解本文内容,需要满足以下条件:

  • 曾经使用过 Microsoft Transaction Server (MTS) 并在 Microsoft Visual Basic® 6.0 中分发过事务。
  • 曾经使用过 COM+ 服务中的基于角色的安全性。
  • 曾经在 COM+ 服务中创建和使用过队列。
  • 非常熟悉 .NET 类。
  • 能够在 .NET 中熟练创建控制台应用程序。
目录

在 .NET 中使用 COM+ 服务

您可能曾经使用 COM+ 应用程序来托管使用 Visual Basic 或 C++ 编写的组件。COM+ 提供了许多有价值的服务,例如事务处理、排队组件、实时激活、基于角色的安全性、共享属性等。使用 COM+ 托管组件的一个主要优点在于:不必编写任何代码,就可以更改组件的行为方式,例如将组件的事务支持设置为“需要”。通过在组件服务 MMC 管理单元中,在 COM+ 组件上设置单选按钮,每次创建组件时,都将在 COM+ 事务的上下文中创建相应的组件。当组件使用 COM+ 事务时,所有数据库事务都由分布式事务处理协调器 (DTC) 处理。图 1 显示了在组件服务界面中设置“需要”事务选项的一个示例。

图 1:需要事务的 COM+ 组件示例

设置组件安全性与设置事务支持一样简单。使用 COM+ 服务管理单元,您不用重新编译代码就可以决定哪个用户可以运行哪个组件,甚至哪个方法。

.NET 可以使用所有 COM+ 服务

在 .NET 框架中,只要您的类是从 System.EnterpriseServices.ServicedComponent 类派生的,就可以继续使用 COM+ 提供的所有服务。任何从 ServicedComponent 类派生的类都由 COM+ 服务托管,并且可以使用所有可用的 COM+ 服务。表 1 列出了 .NET 中支持的全部 COM+ 服务以及每个服务的简短说明。

表 1:可用的 COM+ 服务

COM+ 服务说明
自动事务处理应用声明事务处理功能
COM 事务处理集成器 (COMTI)将 CICS 和 IMS 应用程序封装到自动化对象中
补偿资源管理器 (CRM)对非事务性资源应用原子性和持久性属性
实时激活通过方法调用激活对象,并在调用返回时停用此对象
松散耦合的事件管理基于对象的事件
对象构造在构造实例时向类实例传递持久字符串值
对象池提供现成对象的池
排队组件提供异步消息队列
基于角色的安全性基于角色应用安全权限
共享属性在服务器进程中的多个对象之间共享状态
同步(活动)管理并发
XA 互操作性支持 X/Open 事务处理模型

在 .NET 中使用 COM+ 服务的原因

如果要编写能够参与事务、利用基于角色的安全性或者与队列交互作用的 .NET 应用程序,就会用到 .NET 中提供的 COM+ 服务。正如您将在本文中了解到的,.NET 使这些服务很容易实现。

提示:如果 .NET 代码无需与 COM+ 服务一起工作,也就是说,您只在 .NET 框架中工作,那么请不要使用 System.EnterpriseServices,否则会造成性能下降。

COM+ 组件开发概述

在 .NET 中创建与 COM+ 服务交互的组件时,需要执行以下步骤。表 2 包含对各个步骤的说明。

  1. 创建类库。
  2. 创建所有类,使它们继承 System.EnterpriseServices.ServicedComponents 类。
  3. 创建程序集。
  4. 创建强名称。

    表 2:创建 .NET 组件时使用的术语定义

    术语说明
    类库包含类的 .dll 项目类型,此类项目通常没有用户界面
    System.EnterpriseServices.ServicedComponents.NET 框架中的一个类,使用它才能与 COM+ 服务进行交互
    程序集对项目中所有类和接口的描述
    强名称从程序集生成 GUID,以便可以使用 COM+ 服务注册组件

开发基于事务的组件

在本文的第一部分,您将学习如何创建使用 COM+ 的事务性服务的 .NET 组件,还将学习如何编写组件以及与此组件交互的前端应用程序。

创建 COM+ 事务组件

要使 .NET 组件能够在 COM+ 服务下运行,需要执行以下步骤。首先,必须创建一个从 System.EnterpriseServices.ServicedComponent 类派生的类。这个基类提供了与 COM+ 服务交互所需的所有适当方法和属性。需要将该类标记为需要新事务,并将所创建的任何方法标记为在没有错误出现的情况下可以自动完成事务处理。下面是具体操作。

  1. 打开 Microsoft Visual Studio® .NET,创建一个新的 ClassLibrary 类型的项目。
  2. 将 Class1.vb 文件重命名为 COMPlusServices.vb。
  3. 打开 COMPlusServices.vb 文件,将类名 Class1 更改为 COMPlusServices
  4. 在此新类中键入如下所示的代码:
    Imports System.EnterpriseServicesImports System.Reflection'********************************************' COM+ 注册详细信息 ' 提供 COM+ 应用程序名 <Assembly: ApplicationNameAttribute("ComPlusExample")> ' 提供具有强名称的程序集<Assembly: _ AssemblyKeyFileAttribute("bin/ComPlusExample.snk")>'********************************************<TransactionAttribute(TransactionOption.Required)> _ Public Class COMPlusServices    Inherits ServicedComponent     Public Sub New()        MyBase.New()    End Sub    <AutoComplete()> Public Function DoTransaction() _     As String        Return "COM+ 成功"    End FunctionEnd Class

    此代码以导入多个名称空间开始,从而在声明组件时省略了一些键入内容。

  5. 接下来是 COM+ 注册详细信息。请输入以下代码行:
    ' 提供 COM+ 应用程序名<Assembly: ApplicationNameAttribute("ComPlusExample")> 

此行指定 ApplicationNameAttribute 的值为 ComPlusExample。这是在 COM+ 目录中注册该 COM+ 应用程序时要使用的名称。第一次调用此组件后,当打开 MMC 管理单元的 COM+ 应用程序文件夹时,您会发现应用程序名称就是这个名称。

接下来的代码声明 AssemblyKeyFileAttribute 属性:

<Assembly: _ AssemblyKeyFileAttribute("bin/ComPlusExample.snk")>

此属性通知 COM+ 目录有关强名称的信息所在的位置。在后面的步骤中,将创建用于描述 COM+ 组件的 .SNK 文件。

最后,使用以下代码声明类名 COMPlusServices:

<TransactionAttribute(TransactionOption.Required)> _ Public Public Class COMPlusServices

此类名前面的属性通知 COM+,您要将事务属性设置为“需要”。添加此行代码相当于打开 COM+ 应用程序管理单元(如图 1 所示)并手动设置此属性。

该类中的下一行代码继承 System.EnterpriseServices 名称空间中的 ServicedComponent。

Inherits ServicedComponent 

如果不包含此行,将无法使此组件在 COM+ 下运行。

添加事务方法

现在,类已经设置完毕,可以创建真正能够实现某些功能的方法了。在您编写的代码中,DoTransaction 函数返回一个字符串值,但它只给出了您必须使用的语法,如果不使用此语法该方法将无法参与事务。

<AutoComplete()> Public Function DoTransaction() As String    Return "COM+ 成功"End Function

在此方法前面加上 <AutoComplete()> 属性很重要。这表示只要此方法中没有出现异常,当它结束时就会自动调用 SetComplete。如果该方法中存在异常,则 .NET 运行时将自动调用 SetAbort 方法。这与在 Visual Basic 6.0 中编写 COM 组件不同,在 Visual Basic 6.0 中,必须手动显式调用 SetComplete 和 SetAbort。

创建强名称

在编译组件之前,您需要为此组件的程序集指定一个强名称。如果不指定,COM+ 目录将不能识别该组件,也就无法注册它。实际上,您已经通过前面使用的 AssemblyKeyFile 属性指定了强名称,现在需要使用强名称工具 (Sn.exe) 创建强名称并使 GUID 与程序集关联。

  1. 打开命令提示。
  2. 要创建强名称,请在命令提示下键入以下代码,然后按 Enter 键。
    sn -k ComPlusExample.snk
  3. 将 ComPlusExample.snk 文件从硬盘驱动器的根目录(通常为 C:/)复制到项目所在文件夹的 bin 目录下。

现在,需要编译此程序,使它能生成在 COM+ 注册此组件必需的文件。在 Visual Studio .NET 中,在 Build(生成)菜单上,单击 Build(生成)。

生成客户端测试应用程序

现在,组件生成完毕,需要生成客户端应用程序来调用并测试此组件。创建简单的控制台应用程序,此程序中的模块文件的 Main 方法创建新组件实例,并调用 DoTransaction() 方法。以下是主要步骤:

  1. 在 Visual Basic .NET 中,创建新的控制台应用程序项目。
  2. 添加对刚创建的组件的引用。
  3. 键入如下所示的代码。
    Module modMain    Sub Main()        Dim objCOMPlus As New _         COMPlusJumpStart.COMPlusServices()        Console.WriteLine(objCOMPlus.DoTransaction)        Console.ReadLine()    End SubEnd Module
试一试

最后,运行此程序并查看其运行情况。

  1. 打开组件服务 MMC 管理单元,验证您的组件已经动态注册到 COM+ 目录中。您应该看到图 2 所示的界面。
  2. 编译并运行控制台应用程序。

    图 2:COM+ 目录中的新建 .NET 服务组件

基于角色的安全性

如果多个用户调用在 COM+ 下运行的 COM 组件,您需要进行验证,只允许特定用户访问某个组件。COM+ 允许您定义角色并为其分配 NT 用户。定义并设置角色后,就可以指定哪些角色可以运行哪些组件,甚至指定可以运行组件上的哪些方法。

请在此 COMPlusServices 类中添加一个方法,以添加基于角色的安全性。您需要创建名为 Managers 的角色,并在新方法中进行测试,查看调用者是否为 Managers 角色。

添加基于角色的安全性的步骤

不用直接从组件服务 MMC 管理单元修改 COM+ 应用程序来添加安全角色,只需在项目中添加一个新属性。使用 SecurityRoleAttribute 类添加新的 Managers 角色。这个类的构造函数有两个参数:role(字符串值)和 everyone(布尔值)。role 参数指定要创建的角色的名称,everyone 参数指定是否将内置 Everyone 组添加到此角色的用户中。

  1. 在注释“COM+ 注册详细信息”下键入以下代码,将新的安全性角色添加到 COM+ 应用程序中。
    '********************************************' COM+ 注册详细信息 ' 基于角色的安全性属性<Assembly: SecurityRoleAttribute("Managers", False)>  
  2. 更改安全级别设置,以便在进程级和组件级执行访问检查。这使 COM+ 应用程序具有安全性调用上下文。
  3. 显示 COM+ 服务管理单元。
  4. 单击 Security(安全性)选项卡并更改安全级别,如图 3 所示。

    图 3:在 COM+ 目录中设置安全级别属性

除了手动进行处理外,还可以在组件中添加属性,通知组件执行访问级别检查。以下是在 COMPlusServices 类一开始的“COM+ 注册详细信息”部分添加的代码。

<Assembly: ApplicationAccessControlAttribute   (AccessChecksLevel:=AccessChecksLevelOption.ApplicationComponent)>  

检查安全性角色

现在,将新方法添加到名为 IsManager 的类中。此方法将检查用户是否为具有 Managers 角色的成员。此方法是一个函数,它返回一个布尔值,表明调用者是否为 Managers 角色。要访问调用该方法的用户的安全上下文,需要使用 SecurityCallContext 类。通过调用 CurrrentCall 方法,获得当前用户的上下文。然后调用 IsCallerInRole 方法,并传递 Managers 作为此角色的名称。

  1. 将以下方法添加到 COMPlusServices 类中。
    Public Function IsManager() As Boolean    Dim objCallContext As SecurityCallContext = _     SecurityCallContext.CurrentCall        IsManager = _     objCallContext.IsCallerInRole("Managers")End Function

    现在,需要重新生成该组件以测试此新方法。

  2. 从 Visual Studio .NET 的 Build(生成)菜单中,单击 Rebuild Solution(重新生成解决方案)。
试一试
  1. 修改控制台客户端应用程序的 Sub Main() 方法中的代码。此代码应如下所示:
    Sub Main()    Dim objCOMPlus As New _     COMPlusJumpStart.COMPlusServices()        Console.WriteLine(objCOMPlus.DoTransaction)    Console.WriteLine(objCOMPlus.IsManager().ToString)    Console.ReadLine()End Sub
  2. 在命令提示下键入您编译的可执行文件的名称,运行控制台应用程序。

第一次运行该代码时会发生异常,并说明访问被拒绝的原因是 Managers 角色中没有添加任何用户。要纠正这个异常,请将您自己添加为 Managers 中的用户,并再次运行该应用程序。这次应该不会出现任何异常。也可以在代码中添加异常处理。以下是添加了异常处理代码的客户端应用程序示例:

Sub Main()Try    Dim objCOMPlus As New _     COMPlusJumpStart.COMPlusServices()    Console.WriteLine(objCOMPlus.DoTransaction)    Console.WriteLine(objCOMPlus.IsManager().ToString)    Console.ReadLine()Catch objException As Exception    Console.WriteLine("出现错误。 " _     & "详细信息: " _     & objException.Message)    Console.ReadLine()End TryEnd Sub

使用排队组件

在 COM+ 应用程序中,添加排队支持很简单。只需确保该应用程序作为服务器程序运行(进程外),然后在选项卡上设置 Queued(排队)和 Listen(侦听)属性。完成这些设置后,客户端应用程序就可以异步或同步调用组件。该功能的精妙之处在于,不必更改 COM 对象中的代码,只需在 COM+ 目录中更改其属性。

.NET 框架支持排队组件,而且,正如您期望的那样,您可以通过使用属性,而不用手动更改 COM+ 目录即可为组件提供排队支持。

请在 COMPlusServices 类中添加一个方法,然后在 .NET 客户端应用程序中使用 COM+ 排队组件服务异步调用它。

  1. 将 COM+ 应用程序作为服务器程序(进程外)。这是排队组件的要求。要使用属性达到此目的,请将以下代码添加到项目中:
    '********************************************' COM+ 注册详细信息 <Assembly: ApplicationActivationAttribute(ActivationOption.Server)>
  2. 在组件中添加排队支持。使组件可访问 MSMQ 队列,并使其侦听自己的队列以处理消息。下面是使用属性完成此过程的代码:
    '********************************************' COM+ 注册详细信息 <Assembly: ApplicationQueuingAttribute(Enabled:=True,    QueueListenerEnabled:=True)>
  3. 在类 QueueTest 中添加一个方法。确保它是子例程且不返回任何值。使用它在 Windows 应用程序日志中写入信息。此代码应如下所示:
    Public Sub QueueTest()    System.Diagnostics.EventLog.WriteEntry(_     "COMPlusServces", "队列测试", _     Diagnostics.EventLogEntryType.Error)End Sub

就到这里吧。这就是为使组件成为 COM+ 排队组件需要完成的全部操作。

试一试

现在,应该通过创建另一个控制台应用程序并调用此组件,来尝试运行该排队组件。

  1. 创建新的控制台应用程序。
  2. 将以下代码添加到控制台应用程序的 Sub Main 过程中。
    Sub Main()    Dim objTest As COMPlusJumpStart.COMPlusServices    Dim strMoniker    strMoniker = _      "queue:/new:COMPlusJumpStart.COMPlusServices"    objTest = GetObject(strMoniker)    objTest.QueueTest()End Sub

它将异步调用组件中的 QueueTest 方法。如果要同步调用此方法,可以象调用该组件中的所有其他方法一样调用它。

现在,可以运行此控制台应用程序,尝试运行此排队组件。

自 Visual Basic 6.0 以来 COM+ 的变化

您已经通过 Visual Basic 6.0 或 COM 了解了 .NET 中的许多内容。现在,您已经获得了在 .NET 框架中工作的好处,这有助于实现对象的平稳交互,您只需编写少量代码,执行少量维护即可。

这类简化操作中最典型的是,在 Visual Basic 6.0 中,必须手动显式调用 SetComplete 和 SetAbort。而在 .NET 中,SetComplete 和 SetAbort 由 <AutoComplete()> 属性调用。

Visual Basic .NET 和 Visual Basic 6.0 的另一个不同之处是,由于使用单线程单元线程模型,Visual Basic 6.0 组件不能使用 COM+ 对象池。而 Visual Basic .NET 组件是 .NET 组件,支持任何单元线程模型,所以可以使用 COM+ 对象池。

总结

可以看出,利用 .NET 框架可以方便地利用 COM+ 提供的服务。这意味着您可以将新的 .NET 组件添加到使用 COM 和 COM+ 编写的现有程序中,而且它们可以协同工作。这一点非常重要,因为这意味着您不必放弃现有的全部 COM 和 COM+ 代码。如果您从头开始生成新应用程序,强烈建议您完全在 .NET 框架中生成它,因为这样效率会更高。

关于作者

Tim McCarthy (MCSD, MCT) 是 InterKnowlogy 的总工程师,他利用最新的 Microsoft 技术设计并建立了多层应用程序。他经常在 DevDays 发表演讲,最近刚为 MSDN Field Content Team 编写了 .NET 培训内容。Tim 曾参与编写了许多由 Wrox 出版社出版的书,最近出版的一本书是《Professional VB.NET》。他还为《SQL Server Magazine》的“Developer DotNET Update”时事专栏撰写了多篇文章。

Paul D. Sheriff 是 PDSA, Inc. 的所有者。该公司位于南加利福尼亚州,是一家自定义软件开发和咨询公司。Paul 是南加利福尼亚的 MSDN 区域总监,著有《Paul Sheriff Teaches Visual Basic》一书,他为 Keystone Learning Systems 制作了 70 多套关于 Visual Basic、SQL Server、.NET 和 Web 开发的视频教材,最近还将与 Ken Getz 合作为 SAMS 写一本书,书名是《ASP.NET Jumpstart》。有关详细信息,请访问 PDSA, Inc. 的 Web 站点 www.pdsa.com。

关于 Informant Communications Group

Informant Communications Group, Inc. (www.informant.com) 是一家专注于信息技术行业的多媒体公司。ICG 成立于 1990 年,致力于与软件开发有关的出版物、会议、目录发布和 Web 站点等领域。ICG 在美国和英国均设有办事处,目前已成为享有盛誉的媒体和营销内容集成商,并以高质量的技术信息满足 IT 人员不断增长的需求。

© 2002 Informant Communications Group 和 Microsoft Corporation 版权所有。

技术编辑:PDSA, Inc.

 


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1571448 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值