Before an object instance of a remotable type can be accessed, it must be created and initialized by a process known as activation. In .NET Remoting, marshal-by-reference types support two categories of activation: server activation and client activation. Marshal-by-value types require no special activation mechanism because they’re copied via the serialization process and, in effect, activated upon deserialization.
In .NET Remoting, a type’s activation is determined by the configuration of the .NET Remoting infrastructure rather than by the type itself. For example, you could have the same type configured as server activated in one application and as client activated in another.
The .NET Remoting infrastructure refers to server-activated types as well-known object types because the server application publishes the type at a well-known Uniform Resource Identifier (URI) before activating object instances. The server process hosting the remotable type is responsible for configuring the type as a well-known object, publishing it at a specific well-known endpoint or address, and activating instances of the type only when necessary. .NET Remoting categorizes server activation into two modes that offer differing activation semantics: Singleton mode and SingleCall mode.
No more than one instance of a Singleton-mode–configured type will be active at any time. An instance is activated when first accessed by a client if no other instance exists. While active, the Singleton instance will handle all subsequent client access requests by either the same client or other clients. The Singleton instance can maintain state between method calls.
The following code snippet shows the programmatic method of configuring a remotable object type as a Singleton in a server application hosting that remotable object type:
RemotingConfiguration.RegisterWellKnownServiceType( typeof( SomeMBRType ), "SomeURI", WellKnownObjectMode.Singleton );
This code snippet uses the System.Runtime.Remoting.RemotingConfiguration class to register a type named SomeMBRType as a well-known object in Singleton mode. The client must also configure SomeMBRType as a well-known object in Singleton mode, as the following code snippet shows.
RemotingConfiguration.RegisterWellKnownClientType( typeof( SomeMBRType ), "http://SomeWellKnownURL/SomeURI" );
.NET Remoting provides two mechanisms for configuring the .NET Remoting infrastructure: programmatic files and configuration files. We’ll look at each of these configuration alternatives in more detail in Chapter 3.
Figure 2-4 shows how a Singleton-configured remotable object type handles multiple client requests.
Figure 2-4. Server-activated remote object in Singleton mode
The lifetime management system used by .NET Remoting imposes a default lifetime on server-activated Singleton-configured types. This implies that it’s possible for subsequent client access to occur on various instances of a Singleton type. However, you can override the default lifetime to affect how long your Singleton-configured type can live. In Chapter 3, we’ll look at overriding the default lifetime for a Singleton-configured type.
To better support a stateless programming model, server activation supports a second activation mode: SingleCall. When you configure a type as SingleCall, the .NET Remoting infrastructure will activate a new instance of that type for every method invocation a client makes. After the method invocation returns, the .NET Remoting infrastructure makes the remote object instance available for recycling on the next garbage collection. The following code snippet shows the programmatic method of configuring a remotable object type as a SingleCall in an application hosting that remotable object type:
RemotingConfiguration.RegisterWellKnownServiceType( typeof( SomeMBRType ), "SomeURI", WellKnownObjectMode.SingleCall );
Except for the last parameter, this code snippet is identical to the code used for registering SomeMBRType as a Singleton. The client uses the same method to configure SomeMBRType as a well-known object in SingleCall mode as it used for the Singleton mode. Figure 2-5 shows a server-activated remote object in SingleCall mode. The .NET Remoting infrastructure ensures that a new remote object instance handles each method call request.
Figure 2-5. Server-activated remote object in SingleCall mode
Some scenarios require that each client reference to a remote object instance be distinct. .NET Remoting provides client activation for this purpose. In contrast to how it handles well-known server-activated types, the .NET Remoting infrastructure assigns a URI to each instance of a client-activated type when it activates each object instance.
Instances of client-activated types can remain active between method calls and participate in the same lifetime management scheme as the Singleton. However, instead of a single instance of the type servicing all client requests, each client reference maps to a separate instance of the remotable type.
The following code snippet shows the programmatic method of configuring a remotable object type as client activated in an application hosting that remotable object type:
RemotingConfiguration.RegisterActivatedServiceType(typeof( SomeMBRType ));
The corresponding configuration code on the client application would look like the following:
RemotingConfiguration.RegisterActivatedClientType( typeof( SomeMBRType ), "http://SomeURL");
We’ll look at more detailed examples of configuring and using client-activated objects in Chapter 3.
The RemotingConfiguration class’s methods for registering remote objects follow two naming patterns:
RegisterXXXXClientType methods register remotable object types that a client application wants to consume.
RegisterXXXXServiceType methods register remotable object types that a server application wants to publish.
XXXX can be either WellKnown or Activated. WellKnown indicates that the method registers a server-activated type; Activated indicates that the method registers a client-activated type. We’ll look at the RemotingConfiguration class in more detail in Chapter 3.
Figure 2-6 shows how each client holds a reference to a different client-activated type instance.
Figure 2-6. Client activation