Rickie Lee's blog

Welcome to my blog. I'm mainly involved in .Net platform and corresponding technologies. Thanks.

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  383 随笔 :: 3 文章 :: 1240 评论 :: 97 Trackbacks

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 on 2004-10-20 01:31 Rickie 阅读(2924) 评论(6)  编辑 收藏 所属分类: 1.Remoting技术

评论

#1楼  2006-04-10 16:55 基点项目师      
个人建议,可以考虑使用SAO的伪装CAO模式,使用工厂实现,这样可以避免把业务层部署到客户端,只需要接口
  回复  引用  查看    

#2楼  2006-08-29 23:48 llxisdsh [未注册用户]
这个问题我也正在考虑,不知道SqlCommand行不?
  回复  引用    

我认为采用CAO来部署Remote Objects应该是可行的,不过我具体没有测试过。如果有人测试过,希望能share这方面的体会。
---------------
这样每个字段的赋值都要调用远程对象,性能????


博主的做法的确可以减少代码修改辆,但只是把数据层远程了,业务逻辑修改了岂不是客户端都要升级一遍??


个人认为应该该区分本地接口和远程接口,如果可以加大人力投入的话最好把原来的BusinessRules包装成粗粒度的远程接口。



  回复  引用    

#4楼  2007-02-03 16:09 Deiva [未注册用户]
请问你是怎么样把SqlParameter 序列化了?
  回复  引用    

#5楼  2008-05-26 12:53 thy [未注册用户]
请问你是怎么样把SqlParameter 序列化了?
----------------
我现在也有一个web项目要用到Remoting ,我也想用sqlhelper.cs,但每次提示没有ISerializable物件,请问你是怎么样把SqlParameter 序列化了?

能不能贴段代码?谢谢了
  回复  引用    

#6楼  2008-07-23 10:53 tany [未注册用户]
Remote Objects是可行的,我现在的项目就用的是CAO
  回复  引用    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2004-10-20 02:17 编辑过


相关链接: