.NET COM+ 互操作组件与经典 ASP (第一部分)
使用经典 ASP 调用 .NET COM+ 互操作组件。
引言
一段时间以来,一切都有些枯燥,然后我接手了一项有趣的工作——“经典 ASP 应用程序需要调用新的 .NET 组件”;老实说,.NET 组件的开发决定如此,是因为有一天应用程序将完全转换为 .NET。在本文中,我将尽量将讨论集中在软件开发的实际方面,并使其对开发人员来说易于理解,尽量减少术语的干扰。
背景
我之前做过类似的作业,只是略有不同;前端应用程序是 .NET,而组件是 C++/VB6。我立即开始工作,并在各种问题上摔了很多次跤。如果结局是好的,一切都是好的。
编写 C# 组件就像赤脚走在青草地上一样容易,尽管 log4net 在配置文件方面带来了一些问题;最终,我转向 ASP 应用程序来使用 C# 组件。要么自由,要么壮烈;这是两个选择,要么只使用 .NET 组件,要么同时使用两者,并享受两者的好处,而无需将所有东西都转换为 .NET 的开销。
有很多选择,应该在检查性能、风格、开发便捷性和调试便捷性后做出决定;相信我,不同的组织有完全不同的风格,但业务仍然照常进行,也就是说,没有正确或错误的方式,一切都取决于业务和需求。
一种选择是使用 **tlbexp** 来准备 DLL 以供 ASP 应用程序使用。它需要另一个步骤,即使用 *regsvr32* 注册 DLL;正如你可能记得在使用 C++/VB 项目时,注册是必需的。
第二种选择是通过一个命令进行注册和导入;**regasm**:此命令创建类型库并注册程序集。注册程序集是必需的,因为 VB6/C++ 代码以二进制兼容性进行注册。
第三种选择是使用 **regsvcs** 创建服务;regsvcs 创建类型库,注册 DLL,并创建 COM+ 服务。我喜欢这个,因为你可以获得很多 COM+ 的好处,如事务排队等。请参考 COM+ 书籍进行进一步阅读,正如我之前提到的,我会尽量避免理论。
第一种和第二种选择实际上是相同的,所以从某种意义上说,有两种选择,我从第一种开始,后来喜欢第二种,因为我在做这个项目。我纯粹基于我的知识以及代码需要由更熟悉 VB 而非 .NET 的开发人员维护的需求来决定。
我有许多层,我不确定是否需要创建类型库和/或注册较低层;同样,是否应该注册被暴露程序集引用的其他程序集。我猜测这是不必要的,因为它最终会运行 .NET 程序集;TLB 只是一个 CCW 包装器,不包含其余的程序集/二进制代码。
开始编码
准备好了吗?让我们开始吧……
程序集需要作为 COM+ 服务来使用,以下是使其可用的步骤。这些步骤不是顺序的,你可以根据需要更改顺序,但有些步骤依赖于前面的步骤。
第 1 步:添加对 InteropServices
的引用;这使得你的组件对 COM 和企业库可见,并提供核心的 COM+ 功能。ServicedComponent
是 EnterpriseServices
命名空间的一部分,你将在接下来的步骤中看到类必须继承 ServicedComponent
。在类顶部的其他 using
语句之后添加以下行。
using System.Runtime.InteropServices;
using System.EnterpriseServices;
通过添加这些引用,你将获得其余步骤的智能感知。 ;-)
第 2 步。在命名空间标记之前,为程序集分配名称、描述、激活、事务和其他信息。你可以给出任何名称,默认情况下,它将使用项目名称。有很多选项可用,我为我粗糙的代码选择了一些必要的东西。你只需要将这些添加到你暴露给 COM+ 的类中。这个类使用的其余类可以保持干净,并且不需要在项目中再次输入这些条目。
[assembly: ApplicationName("JayTest")]
[assembly: Description("Jay Test business layer com+")]
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(false,
AccessChecksLevel = AccessChecksLevelOption.ApplicationComponent)]
namespace busLayer
{
GUID 可以轻松使用 VS2005 中的“创建 GUID”工具生成。
第 3 步:GUID;正如你所记得的,为了二进制兼容性,类上的 GUID 是必需的,以使类具有唯一的类 ID。不用担心 ServicedComponent
,因为它将在后面的步骤中进行解释。
[GuidAttribute("ADF0D549-D84B-422c-A15E-5B22C1E35FB5")]
public class JayClass :ServicedComponent
{
第 4 步:使 DLL COM 可见。当然,你需要这样做,并将以下代码放在 ApplicationInfo.cs 中。它是不言自明的,并且应该设置为 true
;如果你不这样做,程序集就不能被使用,你将在 CreateObject
调用中收到一条错误消息。
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(true)]
第 5 步:ServicedComponent
:这个主题可以占用一整章或一本书,但遵循 KISS 原则,你暴露的 COM+ 类必须继承 ServicedCompnent
;否则,在创建服务时,你将收到一条消息,说没有可服务的组件。请参阅第 3 步中的代码。
第 6 步:使用强名称密钥文件签名你的程序集。你可以在项目属性屏幕上的“签名”选项卡中选择一个新的,或者使用 sn.exe 生成一个强名称密钥。
第 7 步:编译代码,并希望你一切都做得对,你将在组件服务中看到该组件。哦,哦……在成功编译后,有一个创建 COM+ 组件的技巧。
在“属性”屏幕上,单击“生成事件”。在“预生成事件”中输入“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regsvcs /u $(TargetFileName)”,在“后生成事件”中输入“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regsvcs $(TargetFileName)”。如你所知或所猜,/u 是取消注册组件,预生成事件会取消注册组件,后生成事件会注册组件。运行 **regsvcs** 需要完整的路径——这是一个 bug。
第一次,未注册将失败,因为组件不存在,所以请在前面输入 **rem** 注释掉预生成事件。你也可以从 VS2005 命令提示符运行这些命令。我可以在后生成事件中放入两个命令,但注意到编译会失败,因为组件正在被其他进程使用。
注册后,打开“组件服务”以验证你的组件是否存在于 COM+ 应用程序列表中。
你可以通过“开始”–“设置”–“控制面板”–“管理工具”–“组件服务”打开“组件服务”。
组件上的“+”号将是固定的,这表明组件存在但未运行,并且不需要启动,因为它将在第一次调用时自动启动,或者你可以通过右键单击并选择“启动”来启动它。你可以右键单击 COM+ 组件并单击“属性”来设置运行组件的用户 ID、池大小、安全性、排队等属性。
我通常根据性能基准测试来设置池,你可以在服务器上尝试调整它来比较性能。你也可以将其设置为服务,它将显示在你的计算机上的其他服务旁边。同样,不详细介绍,因为你可以在许多书籍和文章中阅读到这些内容。
第 8 步:最后但同样重要的是,从应用程序调用 COM+ 组件。
创建一个 ASP 页面和代码来创建 COM+ 组件的对象,使用
dim oBus
set oBus = server.CreateObject("busLayer.JayClass")
创建对象后,调用你想要的方法,例如……
rtnVal = oBus.MyLog("asp msg")
这部分很枯燥,我希望每个人都理解旧的 VBScript。
我正在使用 log4net .NET 组件来记录消息;有关 log4net 开源应用程序的详细信息,请访问这里,它将重定向到新所有者 Apache。
无需将程序集复制到 GAC 或将任何 DLL 复制到 system32 文件夹。
所有 log4net 代码都不属于本文的范围,我将在其他时间撰写相关内容。同样适用于在 .ENT 应用程序中使用 VB6 组件,我从 .NET 调用过 VB6/C++ 组件,我认为这比在 VB6/VBScript 中使用 .NET 组件更容易(只需添加非托管组件的引用,或运行 tlbimp),因为注册表问题不会出现。
欢迎您提供评论,这可以为我节省几个小时与代码搏斗的时间,并且也会帮助我们其他人。
在第二部分,我将解释 .NET COM+ 组件的调试。
关注点
关于方法重载的说明:方法重载不能与 COM+ 一起使用,因为方法名称会自动附加一个后缀,当你尝试调用该方法时,你会收到一条错误消息,提示参数或参数类型不正确。这是另一个难以理解的问题,花了我几个小时(;-|)。
想使用 Web 项目或测试项目调试你的应用程序吗?阅读第二部分。