基于.Net Remoting的项目总结报告

Based on .Net Remoting Project Summary Report

 

 

任务:将一个Windows formsClient/Server程序改写为基于.Net Remoting的程序,由IIS承载Remote Objects

 

1,Windows form的Client/Server系统架构:


包含5个主要的子系统:WinUI(用户界面部分),BusinessRules(业务逻辑部分),DataAccess(数据访问部分),ApplicaitonFrameworks(负责系统参数配置和一些通用class),ExceptionManagement(负责所有系统的异常处理及log

 

2,转换为基于.Net Remoting系统的若干思路

本来准备将BusinessRules子系统部署为Remote Objects,标示为SAOSingleCall/Singleton),但立即发现了一个问题。

因为Business Class几乎都是Fileds成员变量+Public方法组成的,也符合对象技术的基本定义:将数据和操作行为(方法)包装在一起。

如果将Remote Objects部署为SAOSingleCall,任何对Remote ObjectsPublic Accessors赋值/调用都会产生新的对象实例,也就是说Remote Objects是无状态的。

如果将Remote Objects部署为SAOSingleton,显然这样也行不通,因为共享一个Remote Object实例,Fields成员变量会混乱。

 

虽然可以通过将方法参数直接传入,完全不使用Fileds成员变量,这样就可以解决上述问题,但是这样存在很多问题:

1)首先,程序修改工作量巨大,我最讨厌这种没有创造性的重复工作。

2)在Class不使用Fileds成员变量,我觉得这样违背了对象技术的基本定义:将数据和操作行为(方法)包装在一起。另外,也丧失了使用Fileds成员变量的好处,使程序的可读性及可维护性下降。

3)设想方法中包括N多的参数,并且多个方法都是类似的参数列表,显然不能接受。或许有人提出可以采用参数类/Entity Class来传参数,这样会产生很多的参数类,并且也违背对象技术的基本定义。

 

***

这样,可以考虑将Remote Objects部署为CAOClient-Activated Object),CAO对象基本上和正常的.Net Object一样。当在Client端发出创建实例对象的请求(通过Activator.CreateInstance() or new关键字),一个激活消息将发送到Server端,然后Client端的Proxy Object并获取一个指向Remote ObjectobjRef对象。

CAO对象是有状态对象(stateful object),Client端对Remote Object的属性赋值后,可以在下一次正确读取,并且CAO对象在每一次方法调用都保持状态信息。

 

为了减少对WinUI/BusinessRules子系统的修改,显然采用CAO对象的Direct/Transparent Creation方法,具体可以参考《MarshalByRefObjects远程对象及其调用方法》,其中也有一些drawback需要注意。

 

我认为采用CAO来部署Remote Objects应该是可行的,不过我具体没有测试过。如果有人测试过,希望能share这方面的体会。

 

***

具体项目中,因为DataAccess子系统基于SqlHelper.cs类(Microsoft Data Access Application Block v2.0),无法直接将SqlHelper.cs部署为Remote Objects,前面的posting尝试RemotingSqlHelper的若干问题有详细的讨论。

 

虽然可以将SqlHelper.cs改写为可以部署为Remote Objects对象,我也的确做了一些尝试。正是由于尝试RemotingSqlHelper的若干问题》提及的一些局限,同时也避免对BusinessRules子系统的大量修改。

 

最终尝试了如下的方法,并且在实际系统中验证是可行的。

 

 

3,基于.Net Remoting 的系统架构:


具体思路是这样的:

1)将原来的DataAccess子系统部署为Remote Server,并改为RemoteDataAccess子系统,由于SqlHelper.cs不能直接部署为Remote Object,因此在外面包装一个RemotingSqlHelper Class,将RemotingSqlHelper部署为Remote Object

2)增加新的DataAccess子系统,该子系统负责接受来自BusinessRules子系统的调用,因此需要伪装为SqlHelper.cs的模样,否则BusinessRules子系统需要修改的地方就多了。

3)并且新的DataAccess子系统并不直接访问SQL Server Database,而是访问RemotingDataAccess子系统中的RemotingSqlHelper Class

 

其中需要注意的问题:

1SqlConnection对象以connection string代替,我一直习惯使用connection string,因此这个也省事了。

2SqlParameter对象-我定义了一个可序列化的Class,在DataAccess端,将SqlParameter对象转为可序列化的Class。然后在RemotingSqlHelper class中还原为SqlParameter对象,并调用真正的SqlHelper class

 

这样,整个转换过程就大功告成了。其中BusinessRules子系统需要修改的地方很少,几乎不用改。

 

不过,当有大量数据记录从Server端传递到Client端时,比较明显感觉到性能受到影响。Remote ServerIISChannelHTTPIIS不支持TCP Channel),FormatterBinary

 

在此,也感谢一些friends对上述Posts的回复/评论,对我有不少启发。

 

当然,如果设计一个全新的基于.Net Remoting的系统,就不要费这么多周折了。

posted @ 2004-10-20 01:31  Rickie  阅读(4460)  评论(6编辑  收藏  举报