分享
 
 
 

Effective C#: 4.使用类厂(Class Factory)模式实现基于接口的客户激活远程对象(下)

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Effective C#: 4.使用类厂(Class Factory)模式实现

基于接口的客户激活远程对象(下)

陈铭 Microsoft C#/.NET Asia MVP

难度:7/10 条款3

至此,关于SAO对象编译和发布的问题已经解决。再让我们回过头来看一下关于CAO对象的类似问题,是否可以同样通过使用接口来解决问题呢?

照例,我们从一个完整的应用实例开始:

//share.cs, Remote Object

namespace Effective.CSharp.Chapter4 {

//Exactly same as the original one

public class RemoteObject : System.MarshalByRefObject {

//a very simple method implementation

public string SayHello(string name) {

return "Hello, " + name;

}

}

}

//server.cs, Server side code

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

namespace Effective.CSharp.Chapter4 {

public class Server {

public static int Main() {

//Register the channel

TcpChannel chan = new TcpChannel(8085);

ChannelServices.RegisterChannel(chan);

//Register the client activated remote class

RemotingConfiguration.ApplicationName = “MyServer”;

RemotingConfiguration.RegisterActivatedServiceType(

typeof(RemoteObject));

//Hold the server, wait for client

System.Console.WriteLine("Hit <enter> to exit...");

System.Console.ReadLine();

return 0;

}

}

}

//client.cs, Client Side code

using System;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

namespace Effective.CSharp.Chapter4 {

public class Client

{

public static int Main()

{

TcpChannel chan = new TcpChannel();

ChannelServices.RegisterChannel(chan);

//Register at client side

RemotingConfiguration.RegisterActivatedClientType(

typeof(RemoteObject), "tcp://localhost:8085/MyServer");

//Create the remote object

RemoteObject obj = new RemoteObject();

Console.WriteLine(obj.SayHello("World"));

return 0;

}

}

}

显然,在CAO对象的编译和发布方面,我们会碰到与SAO对象完全相同的问题。Client.cs的编译和运行离不开share.dll。CAO对象的应用还有几处明显的不同:CAO对象不仅要求在服务器端进行注册,而且在客户端也需要完成一定的注册工作;更重要的是,CAO对象是通过new创建的!后者彻底阻断了简单的通过接口解决问题的幻想——不可能通过new创建出接口的实例,而必须显式的指明要创建的实现特定接口的类型名称!

很高兴看到你愿意进一步深入了解.NET Remoting的具体运作。J

先来看一下.NET内部是如何根据客户请求创建CAO对象的。.NET Remoting服务会注册一个通用的Singleton SAO对象,用于处理所有创建CAO对象的请求。这个SAO对象实现了IActivator接口,其缺省URI为<application name>/RemoteActivationService.rem,其中application name可以通过RemotingConfiguration. ApplicationName进行设置。

当客户程序执行new语句创建远程对象时,实际上客户端的.NET Remoting服务会通过远程对象的URL地址连接到服务器端相应的RemoteActivationService.rem入口(上面的例子中是"tcp://localhost:8085/MyServer/RemoteActivationService.rem"),调用SAO对象IActivator接口的Activate方法;Activate方法会根据参数查找所有在服务器端注册过的CAO对象类型,如果找到相对应的注册信息(包括类型名称、所在的类集以及版本等),Activate就会根据这些信息创建一个该对象的实例,并且为新创建的对象生成一个唯一的URI入口,然后将该对象返回给客户端。这样,此后的客户方法调用就会与这个特定的CAO对象实例对应起来。(其中为新生成对象指定URI的部分会由底层的.NET Remoting服务自动完成,Activate需要做的仅仅是生成一个新的对象,并且返回该对象的引用)。

可见,远程对象的客户激活机制仅仅是架设在SAO基础上的一层包装,在简化程序员工作的同时,这种客户激活机制也剥夺了对CAO对象使用接口和抽象基类的权力。既然.NET对CAO对象的实现没有用到任何特别的方法,我们就完全可以模仿系统实现自己的CAO机制,只需少许更改,就可以为子定义的CAO提供基于接口的创建方法。

不难看出在整个CAO实现体系中,IActivator实际上是作为一个通用类厂(Class Factory)接口出现的,所以我们也需要针对IRemoteObject接口定义自己的类厂接口IRemoteFactory:

//share.cs, Remote Object and Factory interface

namespace Effective.CSharp.Chapter4 {

public interface IRemoteObject {

string SayHello(string name);

}

public interface IRemoteFactory {

IRemoteObject CreateInstance();

}

}

在服务器端的代码中,我们需要实际实现RemoteObject和一个用于创建RemoteObject的类厂,并且将后者注册为SAO对象:

//server.cs, Server side code

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

namespace Effective.CSharp.Chapter4 {

public class RemoteObject: MarshalByRefObject,

IRemoteObject {

public string SayHello(string name) {

return “Hello, “ + name;

}

}

public class RemoteFactory: MarshalByRefObject,

IRemoteFactory {

public IRemoteObject CreateInstance() {

return new RemoteObject();

}

}

public class Server {

public static int Main() {

//Register the channel

TcpChannel chan = new TcpChannel(8085);

ChannelServices.RegisterChannel(chan);

//Register the client activated remote class

RemotingConfiguration.RegisterWellKnownServiceType(

typeof(RemoteFactory),

"MyFactory.rem", WellKnownObjectMode.Singleton);

//Hold the server, wait for client

System.Console.WriteLine("Hit <enter> to exit...");

System.Console.ReadLine();

return 0;

}

}

}

最后,客户端的实现代码也略有不同:必须先通过Activator.GetObject得到IRemoteFactory接口,然后在需要创建RemoteObject的时候调用IRemoteFactory.CreateInstance:

//client.cs, Client Side code

using System;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

namespace Effective.CSharp.Chapter4 {

public class Client

{

public static int Main()

{

TcpChannel chan = new TcpChannel();

ChannelServices.RegisterChannel(chan);

IRemoteFactory factory =

(IRemoteFactory)Activator.GetObject(

typeof(IRemoteFactory), "tcp://localhost:8085/MyFactory");

//Create the remote object

RemoteObject obj = factory.CreateInstance();

Console.WriteLine(obj.SayHello("World"));

return 0;

}

}

}

在以上所有应用接口的实例当中,我们同样可以使用抽象基类代替接口(关于抽象基类和接口的比较,详见条款X)。

对于应用.NET Remoting技术的分布式应用程序开发,使用接口以及基于接口的类厂是比较好的设计方案,因为这种方案不仅提供了更加清晰的应用模块结构,而且具有更好的可扩展性。

* 本文系原创作品,未经作者本人许可请勿转载。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有