分享
 
 
 

Factory Pattern for CAO Creation

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

Introduction

How do I instance a CAO object without shipping the source object? This is a question I hear often when people begin to work with CAO objects. I've heard this question often enough that I decided to put together an article describing step by step (so you can follow along with your own implementation) one of the better methods of solving this problem. This method is commonly referred to as the Factory Pattern for CAO Creation.

Remoting

Remoting is one of the great innovations of the new .NET framework. It allows for extremely powerful and easy to set up component linking over local or wide area networks. Things that could take days to write and debug in DCOM, COM, ATL, MFC take minutes with .net and remoting.

Remoting has several flavors depending on what you need. For this particular article I will be focusing on Client Activated Objects. Client Activated Objects are stateful objects that reside on the server with a proxy on the client. There are a few principal ways to instance a Client Activated Object, however I will be covering the most desirable of these which is the Factory Pattern for CAO's. The Factory Pattern is an MS recommended way of creating CAO objects without needing to ship the fully implemented object.

I've become familiar with CAO's due to some requirements at work for objects that take a very long time to authenticate against a very old legacy system. Re-authentication on every call wouldn't be practical so I created CAO objects to hold the authenticated state. (Doing this securely requires a bit more trickery than I have time to explain in this article, but I will include them in a future article dealing with remoting objects). I also used CAO objects heavily when I created the GCS Version Control System which used CAO objects to deal with multi-call sessions that would otherwise require large amounts of data to be resent on every connection with Singlecall objects. I am trying to redesign that system though to use Singlecall objects.

Despite how useful CAO objects can be I would be remiss if I didn't state that you should avoid using CAO objects if possible. SAO Singlecall objects are a much better choice for most applications and offer much more flexibility and scalability. Before you embark on your CAO object you should first carefully evaluate your project and see if there isn't a way to do what you need efficiently with an SAO Singlecall object first.

Background: Common Remoting Types

Server Activated Objects : Stateless - Singlecall

This object type is the most prevalent and is recommended by Microsoft for use as the primary remoting type. Server activated Singlecall objects hold no state, which makes them ideal for use with clustered web servers, object pooling, and all other sorts of useful things. Since there is no state held in the object, you have to pass all the data that the object needs to do its work on every call.

Server Activated Objects : Stateful - Singleton

These objects are used when you need both a stateful object AND you need that objects data to persist over time and multiple instantiation. If 3 computers instance an SAO Singleton on a server, they will all get a reference to that same object. Singletons are commonly used to direct access to scarce resources and should generally be avoided when possible.

Client Activated Objects : Stateful

CAO Objects are used when you need an object to be stateful throughout its lifetime to its caller. CAO Objects persist data to their caller, however they are different from SAO Singletons in that multiple instantiations of a CAO will get brand new instances of that CAO each time.

The problem : CAO Creation without distributing CAO Source

There are 3 primary ways of creating a CAO Object that I know of. Creating a CAO requires either a copy of the CAO class on the client, a cumbersome class def created through soapsuds, or the presence of an SAO class factory.

Pros

Cons

CAO Class visible to client

The simplest method of CAO class creation.

You must ship your entire CAO implementation with the client. Almost always an undesirable situation.

Soapsuds class def creation

Allows you to keep the implementation for CAO class hidden on server.

Extremely cumbersome. Every time you change anything you must regenerate new class def.

SAO CAO Class Factory

Allows you to keep the implementation for CAO class hidden on server. Only requires a share dll to allow instantiation on client. Once setup, is extremely flexible to change and update.

A little more complicated than other methods.

SAO CAO Class Factory

SAO Class Factory creation of CAO objects involves instantiation of an SAO Object (usually Singlecall, although for more complicated tracking reasons some people choose Singletons) which then is used to create a CAO object on the server and pass a reference back to the client. This fairly straightforward sequence produces a CAO object reference on the client that requires none of the CAO class code to reside on the client.

For this example I am going to create a very simple CAO from an equally simple SAO Singlecall class factory. To start with we first need to create a dll we will call 'sharedll.dll'. Also create two console applications called Client and Server. Add these all to the same solution so we can compile and examine the files easily.

After we are done our relevant class and exe breakdown will be as follows.

Step by Step

Now that I've explained the basics, lets get down to the code. I am going to walk you through the steps of going from 0 to a working CAO from an SAO class factory.

Step 1: Setting up definitions. Create a solution and add a class library (I called mine ShareDLL), a console app called Client and a console app called Server. Build the solution, then go to the ref section of Client and Server and add a reference to the ShareDLL to both. Also go into the class files for the client and server and add the using ShareDLL (assuming you used this name for your namespace on the ShareDLL). This will allow both the Client and Server to see the class definitions we will store in the ShareDLL.

Add two abstract classes SAOCAOClassFactoryDef and CAOClassDef to the class library and inherit them from MarshalByRefObject. These two classes will serve as the basis for the common types that both the client and server see. The classes are marked abstract because we will only ever use them as a definition that points to the actual implementation which will be in the server.

Go to the server and add two corresponding classes SAOCAOClassFactory and CAOClass that inherit from their corresponding Def parents. These will serve as the implementation classes where the actual work goes on.

// SAOCAOClassFactoryDef.cs in project ShareDLL

public abstract class SAOCAOClassFactoryDef : MarshalByRefObject

{

public abstract CAOClassDef CreateCAOClass();

}

// SAOCAOClassFactory.cs in project Server

public class SAOCAOClassFactory : ShareDLL.SAOCAOClassFactoryDef {}

// CAOClassDef.cs in project ShareDLL

public abstract class CAOClassDef : MarshalByRefObject

{

public abstract int IncrementCounter( int IncSize );

}

// CAOClass.cs in project Server

public class CAOClass : ShareDLL.CAOClassDef {}

Step 2: Fill in functionality of SAO and CAO

Now that we have our classes defined, lets fill in the functionality. We first need to add a function to the SAO object that creates the CAO object. We do this by adding a function CreateCAOObject to the SAO object that instances the object on the server. Remember to add the abstract definition for the function to the sharedll.

Lets also add some functionality to the object so we can test what makes a CAO unique. I added a variable _Counter in the CAO to show that it doesn't lose state between calls. And I added a method (IncrementCounter) that returns the current value of the counter.

// SAOCAOClassFactory.cs in project Server

public class SAOCAOClassFactory : ShareDLL.SAOCAOClassFactoryDef

{

public override CAOClassDef CreateCAOClass()

{

return new CAOClass(); // class factory create

}

}

// CAOClass.cs in project Server

public class CAOClass : ShareDLL.CAOClassDef

{

protected int _Counter = 0; // server side persistent variable

public override int IncrementCounter( int IncSize )

{

_Counter += IncSize;

return _Counter;

}

}

Step 3: Serve your objects

Now our objects are ready to be used so lets serve them. First we create a channel (I chose port 8675). After that you need to register the object with the remoting configuration. This will start the object listening. Remember, we are not serving the actual CAO object. We are serving a Singlecall version of the SAO object that we will use to instance our CAO object. This is an important distinction so don't be spooked by seeing all the SAO types with no reference to our CAO type.

[Code Based Option] -------------------------------------------

// server.cs in project server

ChannelServices.RegisterChannel( new TcpChannel(8675) );

Type SAOType = Type.GetType("Server.SAOCAOClassFactory,Server");

RemotingConfiguration.RegisterWellKnownServiceType(

SAOType, "SAOCAOClassFactoryURI", WellKnownObjectMode.SingleCall);

[Config File Option] -------------------------------------------

// Server.exe.config

<configuration>

<system.runtime.remoting>

<application>

<channels>

<channel ref="tcp" port="8675" />

</channels>

<service>

<wellknown mode="SingleCall"

type="Server.SAOCAOClassFactory,Server"

objectUri="SAOCAOClassFactoryURI" />

</service>

</application>

</system.runtime.remoting>

</configuration>

// server.cs in project server

RemotingConfiguration.Configure( @"..\..\Server.exe.config" );

// change this when you go into production

Step 4: Instantiate your objects

Now that we have the object available lets see about instancing it on the client. Instancing the CAO object is extremely simple compared to the server because we merely need to call a method on the SAO object to get an instance of a CAO object. Note: I don't provide a config file option for the client because with only abstract objects visible to the client (by design) there isn't any way to instantiate them with new. There are ways around this but they are a bit kludgy and get away from the spirit of this article.

// client.cs in project client

string url = "tcp://localhost:8675/SAOCAOClassFactoryURI";

Console.WriteLine("Creating SAO.");

SAOCAOClassFactoryDef cf = (SAOCAOClassFactoryDef)Activator.GetObject(

typeof(SAOCAOClassFactoryDef), url);

Console.WriteLine("Creating CAO from SAO Class Factory!");

CAOClassDef mycao = cf.CreateCAOClass();

Console.WriteLine("CAO Created Successfully.");

Console.WriteLine("First call " + mycao.IncrementCounter(2).ToString());

// output is 2

Console.WriteLine("Second call " + mycao.IncrementCounter(3).ToString());

// output is 5 (proof that object held previous state)

And that is all you need! You now have a working CAO object taken from an SAO class factory. Run the server first, then run the client, the output should look as seen below. Good luck!

Remarks

In trying to keep this article on point I have kept things as simple and concise as possible. I am writing another article that drills deeply into some of the more interesting aspects of remoting objects in general including lifetime management, security tricks, callbacks, etc that I left out of this one. I've tested all the code several times to make sure I didn't include any errors, however if you do find any mistakes or have any questions, feel free to email me allen@glacialcomponents.com. Lastly, I considered adding vb examples as well as c# but I didn't know if there would be any demand for it. If enough people feel it would be helpful I'll add them.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有