日期:2009-10-16  浏览次数:21351 次

如果您符合以下几种情况,这篇文章正适合您:

从 Active Server Pages (ASP) 代码调用组件
设计将从 ASP 代码调用的组件
希望利用 ASP 代码中的组件

目录
简介
为什么使用组件?
状态管理
范围
分割服务
线程模型
安全性
Server.CreateObject 与 CreateObject
传递参数
事件
OnStartPage/OnEndPage 与 ObjectContext
错误处理
全局变量
分布组件
结论

简介
组件。有人喜欢它们,有人则害怕。害怕组件的人通常都能给您讲一个骇人的经历。让我们面对它:当开始在 ASP 下使用组件时,并不知道什么能伤害您。如果您摔倒了,那么站起来,自己拍干净,然后接着来。在这篇文章中,我将提供从实践中获得的一般指南,帮助您建立更好的基于组件的 ASP 解决方案。

为什么使用组件?
在我开始讨论组件指南之前,值得考虑将组件添加到 ASP 应用程序的价值。许多对组件不熟悉的开发人员总觉得一切都那么新鲜。组件可以为 ASP 应用程序带来以下种种益处:

封装功能和隐藏实现细节
可重用性(包括被不同客户机应用程序重复使用)
知识产权保护
可伸缩性(体现在允许将应用程序分布到多台计算机上)
配置和部署灵活性
性能(尤其在早期绑定是重要因素时)
访问系统,例如 Win32 API 调用或编程语言的任何其他底层功能
键入功能较强(“Visual Basic® 脚本编辑器 [VBScript]”的键入功能较弱,而且 JScript® 也不太好)
业务逻辑与用户界面分离,或者 Web 设计人员与 Web 开发人员分离
利益与付出同在。就增加开发过程的复杂性而论,创建组件解决方案可能更加昂贵。部署和疑难解答也可能变得更困难并成为现实因素。但是,不要让眼前的困难阻碍了长期的利益。如何知道付出的成本是否值得呢?请考虑下列方面:

现有的代码库是如何?
开发队伍的水平和经验怎样?
您对主服务器的控制范围如何?
为特定任务选择了什么样的工具和语言?
存在什么协同问题?
存在性能和可伸缩性的因素吗?
项目时间框架是什么?
谁会继续维护和支持该应用程序?例如,开发小组能介入和接管吗?
审查以上考虑的问题后,请考察您的假设。原型能迅速从设想中得出实际情况。

现在,对组件可能带来的益处有了一定的理解,让我们继续讨论。下面的指南将帮助您获得最大的益处。这些指南可能成为指引您顺利建立更稳定的、可升级的、性能更优的 ASP 组件应用程序的向导。

状态管理
建议
一般来说,在可能的场合尽量使用无状态的组件和无状态的 ASP 页面。组件不应需要状态从一个方法调用到下一个状态。将复杂的状态存储在数据库中。对于简单的数据、沿用 cookies、QueryString 或在页面之间传递数据的隐藏的表单字段。

为什么
服务器资源是有限的。维护组件中的状态意味着应用程序在资源冲突和并发问题时将消耗宝贵的资源。无状态组件将帮助您避免这些问题。无状态组件还提供更多的部署选项,并增强在多个客户机上共享资源的能力。

常见的陷阱
开发人员常犯的错误是设计或使用需要维护状态的组件。请注意防止这种常用于桌面开发的思想。通常,具有桌面开发背景的开发人员会设计出依赖状态的组件。

详细信息
避免使用“ASP 会话”将提高服务器的性能,因为它简化了代码路径并减少了服务器资源的消耗。如果不使用“ASP 会话”,请通过“Internet 服务管理器” (请参阅“Internet 信息服务 [IIS]”文档)禁用“会话”状态。也可以在不需要“会话”的 ASP 页面中使用下面的标记禁用基于页的“会话”:

<%@ENABLESESSIONSTATE=False %>
部署灵活性是另一个重要方面,尤其在 Web 区域中运行应用程序时。如果依赖“ASP 会话”, 则给定用户的请求绑定在指定的 Web 服务器上,因为“会话”状态是服务器专用的。在中间层和 Web 服务器中避免状态,并使用数据库,将使 ASP 请求可由区域中任何有效的 Web 服务器处理。因此, 您将减少竞争,提供更好的冗余,并允许更多的分布选项。

不使用“ASP 会话”而在页间传递数据的其他方法,请参阅下面的“知识库 (KB)”文章:

Q175167 HOWTO: Persisting Values Without Sessions(英文)
Q157906 HOWTO: Maintain State Across Pages with VBScript(英文)
Don Box 在 ActiveX® Q&A(英文) 一文中 还提出有关 MTS 状态管理的更多见解。

范围
建议
通常,请在页面范围内使用组件。页面范围的含义就是在同一页上创建对象、并使用它和释放它 ? 所有这些均在同一页上操作。

标记为“双重”或“单元”的组件在页面范围内都能正常工作。仅在页面范围内使用“单元”模型组件,例如 VisualBasic 组件。如果需要在“应用程序”或“会话”中存储组件,则建议使用“双重”。可以在“会话”或“应用程序”范围内存储标记为“双重”的组件,但组件需要保证线程安全。

为什么
在页面范围内使用组件使服务器资源得以回收。释放资源将使并发问题减到最小程度,并允许可汇集的资源在客户机上共享。另外,页面范围组件避免了影响“会话” 或“应用程序”范围的对象的线程问题。在下面的“线程模型分类”中将详细讨论线程问题。

常见的陷阱
最常见的问题之一就是在“应用程序”范围内存储 Visual Basic 或其他“单元”模型对象。如果您尝试在“应用程序”范围内存储一个用 Server.CreateObject 创建的“单元”模型对象,可以看见下面的错误:

应用程序对象错误 'ASP 0197: 80004005'

不允许的对象使用

/VirDir/global.asa, line 7

不能将带有单元模型行为的对象添加到应用程序的内部对象。

但是,如果使用 <OBJECT> 标记在“应用程序”范围内存储“单元”模型对象,就不会出现运行错误。相反,对象将创建在指定的“单线程单元 (STA)”线程上,并且所有调用都汇集到那个线程 ? 而且是连续地。原因是没有复选该组件的线程模型。很遗憾,在运行时出现了问题。

另一个常见问题是在“会话”范围存储“单元”模型对象,该“会话”范围将用户会话绑定到指定的线程。这个行为严重影响服务器的性能。由于所有调用将连续地汇集到创建该对象的线程,因此从根本上影响了线程缓冲池的目的。

详细信息
有关详细内容,请参阅下面的 KB 文章:

Q243543 INFO: Do Not Store STA Objects in Session or Application(英文)
Q243548 INFO: Design Guidelines for VB Components Under ASP(英文)
分割服务
建议
将表达、业务和数据服务分离。业务组件应该实施业务规则。业务组件不应包含数据访问技术。那是数据层组件的任务。业务组件不应包含对 ASP 对象的引用。

ASP 提供表达服务。引用 ASP 的对象应该呈现为 HTML。这些对象能够依次调用对 MTS/COM+ 注册的业务对象。

为什么
将应用程序分割为单独的和截然不同的服务,有以下好处:

更便于组件的重用
支持 Windows DNA model(英文)
更好地孤立疑难问题
更灵活的部署选项(去掉服务的耦合允许在多台计算机上分布应用程序)
常见的陷阱
有一种我们称为“瑞士军刀”组件的常见问题。 该“瑞士军”组件将所有服务合成一体 (就像有螺丝锥、牙签等 17 种工具的小瑞士军刀)。 把不相关的服务组合到一个组件中, 使该组件很难使用、理解和维护。

容易掉入的另一个陷阱是从业务组件中引用 ASP。使 ASP 和业务逻辑耦合(通过使用 请求或响应对象,或在其内部构建 HTML),不仅限制不同的客户机重用您的组件,而且限制了横向的可伸缩性。引用 ASP 内置对象的对象应该与 Web 服务器在同一框围中。理想情况下,由于横向可伸缩性,业务组件可以分布在不同的框围中。可以直接在 ASP 脚本中提供表达服务,也可以建立呈现引用 ASP 内置对象的组件的 HTML,并将这些组件