IMessageSink
Any type that implements the IMessageSink interface can participate in the .NET Remoting architecture as a message sink. Table 6-1 lists the members of the IMessageSink interface. Table 6-1 Members of Table 6-1 Members of The next message sink in the chain, or null if this is the last sink in the chain Processes the message asynchronously The following code defines a class that implements IMessageSink public class PassThruMessageSink IMessageSink public PassThruMessageSink IMessageSink next...
Making a Type Remotable
To prepare the JobServerImpl class and its supporting constructs for .NET Remoting, we need to enhance their functionality in several ways. Let's start with the JobInfo struct. The JobServerImpl class passes JobInfo structure instance information to the client therefore, the structure must be serializable. With the .NET Framework, making an object serializable is as simple as applying the serializable pseudocustom attribute. Next we must derive the JobServerImpl class, which is our remote...
Context Attributes and Properties
You define and establish a context by attributing the context-bound type with one or more attributes that implement the IContextAttribute interface. Table 6-2 shows the methods that IContextAttribute defines. Table 6-2 Members of Table 6-2 Members of The runtime calls this method to determine whether the current context is OK for activation of the attributed type. The runtime calls this method after an attribute has indicated that the current context isn't OK for activation of the attributed...
Creating a Custom Dynamic Sink
To create a custom dynamic context sink, you need to perform the following tasks Define a dynamic message sink class that implements the IDynamicMessageSink interface. Define a dynamic property class that implements the IDynamicProperty and the IContributeDynamicSink interfaces. In the implementation of the IContributeDynamicSink.GetDynamicSink method, return an instance of the dynamic message sink class. Programmatically register and unregister the dynamic property by using the...
Implementing a Custom Channel Sink
Request and response messages pass from one end of a sink chain to the other. During this traversal, sinks have the opportunity to do work based on the message information. By creating a custom sink, we can hook ourselves into the sink chain and gain access to every message before transmission and after receipt. But custom sinks aren't limited to just manipulating messages. A custom sink could perform some action based on the contents of the message. Finally, custom sinks don't have to be...
ClientFormatterSinkProvider
Now that we have a client formatter sink, we need a channel sink provider class that we can use to install the formatter sink into the client channel sink chain. The following code listing defines the MyFormatterClientSinkProvider class public class MyFormatterClientSinkProvider IC1ientFormatterSinkProvider public MyFormatterClientSinkProvider i I public MyFormatterClientSinkProvider IDictionary properties, ICollection providerData Build the client-side channel sink chain public...
Surrogate Selectors
As we'll discuss in the Serialization Formatters section, one of the properties that a formatter exposes is the SurrogateSelector property. You can set the SurrogateSelector property to any object that implements the ISurrogateSelector interface. Formatters use the surrogate selector to determine whether the type currently being serialized or deserialized has a surrogate. If the type does, the formatter uses the surrogate to handle serialization and deserialization of instances of that type....
Client Formatter Sink
The first sink in the client-side channel sink chain is an instance of a client formatter sink that implements the IClientFormatterSink interface. The client formatter sink acts as a bridge between the message sink chain and the channel sink chain. As such, the client formatter sink is both a message sink and a channel sink. The IClientFormatterSink interface is a composite of the IMessageSink, IClientChannelSink, and IChannelSinkBase interfaces. The following code listing defines a class named...
Finally the message contains information identifying the calling application
lt SOAP-ENC Array id ref-18 lt item href ref-42 gt lt item href ref-43 gt lt SOAP-ENC Array gt lt a3 CrossAppDomainData id ref-42 lt _DomainID gt 1 lt _DomainID gt lt _processGuid id ref-44 gt 20c23b9b_4d09_46a8_bc29_10037f04f46f lt _processGuid gt lt a3 CrossAppDomainData gt lt a3 ChannelDataStore id ref-43 lt _channelURIs href ref-45 gt lt _extraData xsi null 1 gt lt a3 ChannelDataStore gt lt SOAP-ENC Array id ref-45 lt item id ref-4 lt SOAP-ENV Body gt lt SOAP-ENV Envelope gt
ProcessMessage is where we allow or deny method calls If we arent in a blocked
client know we couldn't fulfill its request. Here's the implementation of ProcessMessage public ServerProcessing ProcessMessage IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream If we are not in a blocked time period, send the message down the chain. return m_NextSink.ProcessMessage sinkStack, requestMsg, requestHeaders, requestStream, out...
ServerFormatterSinkProvider
Now that we have a server formatter sink, we need a channel sink provider class that we can use to install the formatter sink into the server channel sink chain. The following code listing defines the MyFormatterServerSinkProvider class public class MyFormatterServerSinkProvider public MyFormatterServerSinkProvider This ctor form provides properties from configuration file, public MyFormatterServerSinkProvider IDictionary properties, private IServerChannelSinkProvider _Next public...
Singleton
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...
Heres the ProxyAttribute listing for our activation example
public class SProxyAttribute ProxyAttribute public override System.MarshalByRefObject CreateInstance System.Type serverType Instance Get a proxy to the real object. MarshalByRefObject mbr base.CreateInstance serverType Are we on the client side or the server side This matters because the .NET Remoting infrastructure on both sides of the boundary will invoke this method. If we are on the server side, we need to return the MBR provided by the previous base.CreateInstance call, rather than our...
Extending RealProxy
To write a proxy to replace RemotingProxy, we need to derive a class from RealProxy and add a new constructor and private MarshalByRefObject, as shown here public MyProxy Type type, MarshalByRefObject target We need to capture the reference to the real MarshalByRefObject so that our proxy can forward calls to the real remote object. We also call the RealProxy's constructor and pass the type of the remote object so that the .NET Remoting infrastructure can generate a TransparentProxy instance to...
TransparentProxy
Suppose you call new or Activator.CreateInstance to instantiate a remote object My0bj obj new My0bj int Result obj.MyMethod As soon as the line calling new returns, MyObj contains a reference to a type named TransparentProxy. The .NET Remoting infrastructure dynamically creates the TransparentProxy instance at run time by using reflection against the real object's metadata. .NET Framework reflection is a powerful technique for examining metadata at run time. Using reflection, the .NET Remoting...
Implementing the Formatter Interface
Serialization formatters are classes that implement the IFormatter interface. Table 8-8 lists the members defined by the IFormatter interface. Table 8-8 Table 8-8 Members of System.Runtime.Serialization. IFormatter Table 8-8 Table 8-8 Members of System.Runtime.Serialization. IFormatter Allows equipping the formatter instance with a SerializationBinder instance to deserialize a serialized type to a different type Can reference a StreamingContext instance that contains information about the...
Implementing the Sponsor Interface
To take full advantage of the lease-based lifetime mechanism provided by .NET Remoting, you can create a sponsor by implementing the Sponsor interface and registering the sponsor with the lease for a remote object. When the lease expires, the runtime will call the Sponsor.Renewal method on any registered sponsors, giving each sponsor an opportunity to renew the lease. For the JobClient application, you can make the Forml class a sponsor by having it derive from and implement the Sponsor...
