|
The first two examples showed us a quick glimpse of object creation. It’s now time to consider all the choices that we have in object creation and the advantages and disadvantages of each. I’ve written a sample program that demonstrates the different types of object activation, which you’ll find in the \Activation sample subdirectory. I’d suggest running the sample server in the debugger so that you can see the object creation traces in its output window. The client, shown in Figure 10-4, demonstrates access to an object through each type. The remoting object that it creates is the same every time, a very simple one containing a single read/write property of type string named MyString. This section doesn’t discuss object lifetime and destruction. That topic is complex enough that it requires its own section, which immediately follows this one.
Remoting provides several choices for object creation.
Figure 10-4: Activation sample client.
The object in our simplest example was called a singleton object, which means that only one physical instance of this object exists at any given time. That instance is created when a client first makes a call on an object of that class. (The client’s creation request only sets up a proxy and channel; it doesn’t actually create the object even though you might think it would. The actual function call causes the object creation, as you can see through the debugger traces.) All clients that subsequently request an object of this type are connected to the same instance, as shown in Figure 10-5. You can verify that the singleton object actually does behave in this manner by running more than one copy of the sample client to access the singleton object. You’ll see that the changes made to the singleton object’s state by each client are visible to the other client. This approach is useful for sharing one service or copy of data among multiple clients. For example, an object that generates sequential receipt numbers would be a good application for a singleton object.
A singleton object provides one instance shared by all clients.
Figure 10-5: Singleton object architecture.
A special case of the singleton object is called the published object. A published object is a singleton object that isn’t created in response to a client call. Instead, the server creates the object when it feels like it, initializes it to whatever state it wants, and exposes (“publishes”) it for clients to use. The function Runtime.Remoting.RemotingServices.Marshal, shown in Listing 10-7, performs this operation. Choose this alternative if you like the singleton model of all clients using the same instance of an object but you want to initialize the object’s state before a client request comes in—for example, loading up a database of foreign exchange deals before opening a bank system for trading in the morning.
A published object is a special case of an initialized singleton.
Listing 10-7: Code for creating a published object.
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles Button2.Click ’ Create object that we want to publish Dim foo As New ActivationObjectsVB.Published ’ Set its state to whatever we want it to be foo.MyString = TextBox1.Text ’ Publish the object Runtime.Remoting.RemotingServices.Marshal _ (foo, "ActivationPublishedURI") End Sub
Another activation type available to you is the single-call object. As with the singleton object, you specify this behavior in the call to RegisterWellKnownServiceType or in your configuration file. The remoting infrastructure creates a new object of this type just in time when it receives a call from the client. When the call returns, the object becomes garbage. When the client makes the next call, the infrastructure creates a new instance of the object, even if the client is using the same proxy and doesn’t think he’s asked for a new instance, as shown in Figure 10-6. The object’s internal state is not maintained from one call to the next, which is exactly the same behavior exhibited by just-in-time activation objects in COM+ and for XML Web service objects. Some programmers consider it a scalability feature because objects don’t consume server-side resources between calls and because they are easier to load balance. On the other hand, the remoting infrastructure has to spend the energy to create the object with every call and to deal with the more frequent garbage collection required by all these discarded objects, so this approach might not be saving any resources. I think of it more as a mechanism for enforcing isolation in objects that participate in transactions. The single-call object dumps its state after every call, so no one can see its intermediate results, which might be invalid because you don’t know whether the transaction will commit or abort.
A single-call object is created anew for each function call made by the client.
Figure 10-6: Single-call object architecture.
The final type of object activation supported in remoting is called the client-activated object. (See why I coined the term MINFU?) This type of object provides the stateful behavior that you expect of “normal” objects. When the client calls the function that creates the object, the remoting infrastructure contacts the host and creates a new instance of the object, sets up the proxy and stub, and provides the proxy to the client. Each object creation request gets a separate instance of the object, and each client call accesses the instance to which its proxy is connected. Changes made to an object’s state are visible only to that object. This behavior is shown in Figure 10-7. The object retains its state until the end of its lifetime, which I’ll discuss in the next section.
A client-activated object provides the stateful behavior you expect of “normal” objects.
Figure 10-7: Client-activated object architecture.
Table 10-1 summarizes the types of object activation I’ve been discussing.
Name | Creation | Good For |
---|---|---|
Singleton | Single instance for all clients; automatically created at first client call | Sharing data between clients when initial state is invariant or you don’t care about it |
Published | Single instance for all clients; explicitly created and initialized by server | Sharing data between clients, with initial state set by server |
Single Call | New instance for each call made by client | Transactional operations |
Client-Activated | New instance for each creation request made by client | Classic stateful object behavior |
|