programming4us
programming4us
ENTERPRISE

Programming .NET Components : Building a Distributed Application (part 5) - Creating Remote Objects

9/29/2012 2:05:02 AM

8. Creating Remote Objects

If the client has registered a type as a remote type (either programmatically or administratively), the client can use the plain new operator to create any kind of remote type, be it client- or server-activated. However, as mentioned already, .NET provides clients with several ways to connect to remote objects. These options differ in their need for pre-registration of the type and in their ability to connect to client-activated objects.

8.1. RemotingServices.Connect( )

The client can choose to connect explicitly to a remote object using the static method Connect( ) of the RemotingServices class:

    public static object Connect(Type classToProxy, string url);

Calling Connect( ) explicitly creates a proxy to the remote object on the client side. You can use Connect( ) only to connect to server-activated objects, and you can use only the default constructor. Using the same definitions as in Example 10-5, here is how to create a remote server-activated object using Connect( ):

    Type serverType = typeof(MyClass);
    string url = "tcp://localhost:8005/MyRemoteServer";
      
    MyClass obj;        
      
    obj = (MyClass)RemotingServices.Connect(serverType,url);
    obj.Count( );

Connect( ) doesn't affect other attempts of the client to create instances of the type, meaning that if no type registration takes place, after a call to Connect( ), calls to new create the type locally in the client's app domain. In fact, you can even register the type, associate it with one location, and then have Connect( ) activate an instance at another location.

8.2. Activator.GetObject( )

The Activator class provides the static method GetObject( ):

    public static object GetObject(Type type,string url);

GetObject( ) works like RemotingServices.Connect( ) does, allowing the client to connect to a server-activated object:

    Type serverType = typeof(MyClass);
    string url = "tcp://localhost:8005/MyRemoteServer";
      
    MyClass obj;        
      
    obj = (MyClass)Activator.GetObject(serverType,url);
    obj.Count( );

GetObject( ) doesn't require type registration on the client side, and it doesn't affect registration of the type.

8.3. Activator.CreateInstance( )

The Activator class provides many overloaded versions of the static method CreateInstance( ). CreateInstance( ) lets you create any object type (client- or server-activated) and lets you have fine-grained control over the creation process. Some of the versions require type registration before invocation. This version:

    public static object CreateInstance(Type type);

is no different from new and creates the instance at the remote location registered:

    Type serverType = typeof(MyClass);
    MyClass obj;        
      
    obj = (MyClass)Activator.CreateInstance(serverType);
    obj.Count( );

CreateInstance( ) also offers a generic version:

    public static T CreateInstance<T>( );

The generic version is, of course, superior to the object-based version, as it is type-safe:

    MyClass obj = Activator.CreateInstance<MyClass>( );
    obj.Count( );

The following version allows you to pass in construction parameters for client-activated objects in the form of an array of objects:

    public static object CreateInstance(Type type, object[] args);

CreateInstance( ) chooses the best-fitting constructor, similarly to how the compiler chooses a constructor. If you want to create a remote instance without registering the type beforehand, use a version that accepts an array of activation attributes:

    public static object CreateInstance(Type type,object[] args,
                                                       object[] activationAttributes);


					  

You can pass in as an activation attribute an instance of UrlAttribute, defined in the System.Runtime.Remoting.Activation namespace:

    using System.Runtime.Remoting.Activation;
    using RemoteServer;
      
    object[] attArray = {new UrlAttribute("tcp://localhost:8005")};
    Type serverType = typeof(MyClass);
      
    //No registration is required:
    MyClass obj = (MyClass)Activator.CreateInstance(serverType,null,attArray);
    obj.Count( );


					  

CreateInstance( ) is available for advanced creation scenarios. This version:

    public static ObjectHandle CreateInstance(string assemblyName,string typeName);


					  

creates an instance of the specified type and delays setting up a proxy and loading the server assembly until the object handle is unwrapped:

    using RemoteServer;
      
    ObjectHandle handle;
    handle = Activator.CreateInstance("ServerAssembly","RemoteServer.MyClass");
      
    //Proxy is only set up here, and assembly is loaded locally
    MyClass obj = (MyClass)handle.Unwrap( );
    obj.Count( );


					  

Note that you have to specify the fully qualified type name. Other versions of CreateInstance( ) allow you to specify locale and security information.

Table 1 compares the various options available when creating or activating remote objects.

Table 1. Creating and activating remote object options
Creating optionRequires registrationClient-activated objectsServer-activated objects
newYesYesYes
RemotingServices.Connect( )NoNoYes
Activator.GetObject( )NoNoYes
Activator.CreateInstance( )DependsYesYes

8.4. Creating remote generic objects

You can use the Activator class to create instances of generic remote objects, such as this one:

    public class MyServer<T> : MarshalByRefObject
    {...}

You need to provide the specific type parameters to use, and you must provide the specific types when explicitly casting the returned object:

    string url = "tcp://localhost:8005/MyRemoteServer";
    Type serverType = typeof(MyServer<int>);
    MyServer<int>obj;
    obj = (MyServer<int>)Activator.GetObject(serverType,url);

You can, of course, also use the generic CreateInstance( ) method to create generic types:

    MyServer<int> obj;
    obj = Activator.CreateInstance<MyServer<int>>( );

It would have been useful if GetObject( ) were to offer a generic version, like this:

    public static T GetObject<T>(string url);
Other  
 
Video
PS4 game trailer XBox One game trailer
WiiU game trailer 3ds game trailer
Top 10 Video Game
-   Minecraft Mods - MAD PACK #10 'NETHER DOOM!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
-   Minecraft Mods - MAD PACK #9 'KING SLIME!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
-   Minecraft Mods - MAD PACK #2 'LAVA LOBBERS!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
-   Minecraft Mods - MAD PACK #3 'OBSIDIAN LONGSWORD!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
-   Total War: Warhammer [PC] Demigryph Trailer
-   Minecraft | MINIONS MOVIE MOD! (Despicable Me, Minions Movie)
-   Minecraft | Crazy Craft 3.0 - Ep 3! "TITANS ATTACK"
-   Minecraft | Crazy Craft 3.0 - Ep 2! "THIEVING FROM THE CRAZIES"
-   Minecraft | MORPH HIDE AND SEEK - Minions Despicable Me Mod
-   Minecraft | Dream Craft - Star Wars Modded Survival Ep 92 "IS JOE DEAD?!"
-   Minecraft | Dream Craft - Star Wars Modded Survival Ep 93 "JEDI STRIKE BACK"
-   Minecraft | Dream Craft - Star Wars Modded Survival Ep 94 "TATOOINE PLANET DESTRUCTION"
-   Minecraft | Dream Craft - Star Wars Modded Survival Ep 95 "TATOOINE CAPTIVES"
-   Hitman [PS4/XOne/PC] Alpha Gameplay Trailer
-   Satellite Reign [PC] Release Date Trailer
Game of War | Kate Upton Commercial
programming4us
 
 
programming4us