Section 1
- Part 2
- Topic 3
Create and serialize remotable types.
- Create a remotable type.
- Create generic types.
- Configure a serialization formatter programmatically.
- Configure a binary formatter.
- Configure a SOAP formatter.
- Implement Version Tolerant Serialization (VTS).
Summary
There are two types of objects that can be remoted. Classes that inherit from MarshalByRef or Marshal By Reference objects are invoked by a client proxy that is dynamically created by the .Net remoting infrastructure depending on the configuration (activation, lifetime, etc). A Context Bound Object is a special type of Marshal By Reference Object that takes it a step further and ensures the objects that inherit from the ContextBoundObject class are in their own context. This is helpful with transactions and multi threading. The other type of object that can be remoted are Marshal By Value types. Any type that can be serialized is considered Marshal by Value types. When a Marshal By Value type is used it is completely copied to the client unlike Marshal By Reference objects which use proxies for communication.
New to .Net 2.0 are Generics. For more information on generics see the guide to exam 70-553. Web Services can not leverage generics in .Net 2.0 because none of the web service standards would support them. However, .Net remoting does support generics and combined with configuration techniques, this is a very powerful approach.
Using Generics you can define one or more type parameters that are defined when you declare an instance of a class. You can use generics with remoting as long as the class still inherits from MarshalByRef. In order for it to work properly, any types must be serializable or derived from MarshalByRef.
//Using Generics with a RemotableType
public class GenericRemotableType<T> : MarshalByRefObject //Using Generics with a RemotableType and constraing the Parameter Type T
public class GenericRemotableType<T> : MarshalByRefObject
where T : MarshalByRefObject
The remoting server and client and utilize these generic types either programmatically or through configuration.
To use configuration to define the type parameters to your objects that use generics, you need only specify the type in brackets in the config file. Below is an example of both server and client configuration from msdn2:
Server Config
<service>
<activated type="RemoteServer.MyServer[[System.Int32]],ServerAssembly"/>
</service>
Client Config
<client url="...some url goes here...">
<activated type="RemoteServer.MyServer[[System.Int32]],ServerAssembly"/>
</client>
You can programmatically configure your remoting clients as well. The following examples the demonstrate this are also from msdn2:
//Host Side Activation and Type Registration
Type serverType = typeof(MyServer<int>);
RemotingConfiguration.RegisterActivatedServiceType(serverType); //Client Side Activation Mode and Location registration
Type serverType = typeof(MyServer<int>);
string url = ...; //some url initialization
RemotingConfiguration.RegisterWellKnownClientType(serverType,url); //Initializing the Remote Server
MyServer<int> obj;
obj = new MyServer<int>();
//Use obj //Using the Activator Get Object
string url = ...; //some url initialization
Type serverType = typeof(MyServer<int>);
MyServer<int> obj;
obj = (MyServer<int>)Activator.GetObject(serverType,url);
//Use obj //Using the Activator Create Instance
Type serverType = typeof(MyServer<int>);
MyServer<int> obj;
obj = (MyServer<int>)Activator.CreateInstance(serverType);
//Use obj //Using the Generic Activator Create Instance
Type serverType = typeof(MyServer<int>);
MyServer<int> obj;
obj = Activator.CreateInstance(serverType);
//Use obj
When a Marshal By Value type is passed between application domains, in needs to be serialized. You can specify how the type will be serialized through configuring it through the formatter node under the serverProvider or clientProvider element in the applications config file. The node can specify the SOAP or Binary Formatter. This node has a includeVersions attribute which can be used to specify that the formatter should include full versioning when serializing types. This is done by default using the Binary Formatter, but not when using the SOAP formatter.
In .Net 1.x the remoting types had to be exactly the same or it would throw an exception. In .Net 2.0, the binary formatter now supports some version tolerance. Using the new OptionalField Attribute you can introduce new fields into your remotable types without breaking existing clients. This does cause some tricky implementation as clients are not guaranteed to have the field, so use with caution.
Other Resources & Links:
Building a Remotable Type
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconremotingexampleasynchronousremoting.asp
Remotable and NonRemotable Objects
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconremotingexampleasynchronousremoting.asp
Using Generics in Remoting through Configuration (Just a Sample)
http://msdn2.microsoft.com/en-us/library/ms180986.aspx
An Introduction to C# Generics (Good Overview of Generics with Remoting)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/csharp_generics.asp
Format for .NET Remoting Configuration Files
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/remotingconfig.asp
Format Your Way to Success with the .NET Framework Versions 1.1 and 2.0
http://msdn.microsoft.com/msdnmag/issues/04/10/AdvancedSerialization/