最近,修改公司的一个旧系统。表示层是用asp写的,业务层是用vb写的com组件,组件在服务器端注册(regsvr32)后,把服务器配置好RDS服务。客户端用vbs脚本通过rds组件来创建远程创建服务端的对象,然后调用对象的各种方法,而且客户端可以直接使用记录集(recordset)来保存和处理数据.这些业务组件主要完成一些对数据库的操作,而客户端vbs来做一些数据验证,用户界面等功能,服务端asp的代码几乎很少。然后再写一些windows服务后台处理,比如说扫描某个表,把定时发送的短信提交给移动网关,还有短信的上行解析,送达回执,回复等都用windows服务来做。整个架构看起来很清晰,也很稳定,没有一点华而不实的东西。
要是让我现在设计这个系统,肯定是ORM+AOP+Ajax了,其实这样也不一定比上面我说的那样的架构好。人家的界面也是无刷新的,通过创建远程对象直接使用客户端的记录集,你用ajax,还得自己用xml存放数据。而且remote data service也相当于.net remting了,也实现了松散耦合,各层的职责划分很清晰。数据访问层就用的ADO,也没用啥ORM框架,但封装的好,调用起来没有很方便,不用关心具体实现细节。
不是说提倡技术倒退,我想的是,几年前就能设计出这么好的架构,而且那时候.net才刚刚出现,现在技术发展的这么快,各种应用框架层出不穷,让人目不暇接。而我却没有真正把一种技术或者一个框架用好,用透彻,惭愧呀。其实把一两个框架用好了就能做出好的应用来,像NBear,NickLee,Entlib,Castle等,真正用好一个也就很厉害了。
由于对VB不熟悉,修改业务组件的时候遇到了不少问题。先总结一下。
1、用asp等脚本调用Com组件的时候要注意参数是否为引用参数。比如说要传一个记录集,不加括号就运行不了,会提示你类型不匹配,加了括号就可以。正确代码(vbs客户端脚本,不是asp)如下:
Set rs = CreateObject("ADODB.Recordset")
Set objSMSSend = ADS1.createobject("SMSSendlib.Sender","http://10.2.11.46")
objSMSSend.SendMessage (rs)
而你在vb里面如果想不用括号的话就要声明rs的类型
Dim rs as Recordset
Set objSMSSend = CreateObject("SMSSendlib.Sender")
objSMSSend.SendMessage rs
或者是
Dim rs
Set objSMSSend = CreateObject("SMSSendlib.Sender")
objSMSSend.SendMessage (rs)
2、开发Com组件的时候,如果你的组件里调用了其它的Com组件,要注意被调用组件的版本。虽然组件的名字相同,但不一定是一样的东西,也许GUID不同吧。比如我在写SMSSendlib.Sender的组件的时候,里面调用了其它的组件,如下:
Dim objMngr As MainBusInterface.IMaintData
Set objMngr = CreateObject("MainBusiness.PvtPhraseManager")
objMngr.DoSamething()
如果MainBusiness.PvtPhraseManager以前在生产环境注册过,而你的SMSSendlib.Sender组件开发的时候用的是新的组件,即使能开发的时候能编译过去,你部署到生产环境,在客户端使用的时候也会出错。会提示“路径/访问错误”,天知道为什么会提示这样一个风马牛不相及的错误。我是这样解决的,我把MainBusiness.PvtPhraseManager里的DoSamething过程给复制到本地,然后生成了一下SMSSendlib.Sender的dll,然后客户端调用就可以了。虽然是一个权宜之计吧,但也勉强解决了问题。
相关链接:
您将参数从 ASP 传递到 VisualBasic 组件时键入不匹配错误信息:
http://support.microsoft.com/default.aspx?scid=kb%3Bzh-cn%3B244012
如何配置 RDS for Windows Server 2003
http://support.microsoft.com/default.aspx?scid=kb%3Bzh-cn%3B837981
解决与远程数据服务常见问题
http://support.microsoft.com/kb/251122/