ENTERPRISE

Programming .NET Components : Remoting - Remote Object Types

8/14/2012 5:37:59 PM
If the referenced object is in the same app domain as the client, usually no proxies are involved, and the client will hold a direct reference to the object. The question is, what happens when you try to call methods on a remote object in another app domain? By default, objects are not accessible from outside their own app domains, even if the call is made from another app domain in the same process. The rationale behind this decision is that .NET must first enforce app domain isolation and security. If you intend your objects to be accessed from outside their app domains, you must allow this explicitly in your design and class definition. .NET provides two options for accessing an object across an app domain boundary: by value or by reference. Accessing an object by value means that when a client in App Domain 2 calls a method on an object in App Domain 1, the object is first copied to App Domain 2, so the client gets its own cloned copy of the object. Once a copy is transferred to the remote client, the two objects are distinct and can change state independently. Any change made to the object's state in App Domain 2 applies only to that local copy, which is completely separate from the original object. This is often referred to as marshaling by value and is similar to the analogous behavior in COM. The second way to access a remote object is by reference. In this case, the remote clients hold only a reference to the object, in the form of a proxy. Access by reference is often referred to as marshaling by reference (which was the standard behavior provided by COM).

1. Marshaling by Value

When an object is marshaled by value, .NET must make a copy of the object's state, transfer the state to the calling app domain, and build up a new object based on that state. There are some difficulties, however. .NET needs to know which parts of the object's state can be marshaled by value and which parts can't. .NET has to obtain the state of an existing object and then build a new object based on that state. And what if the object also wants to provide some custom marshaling-by-value mechanism? Luckily, .NET already has the infrastructure to handle such issues: serialization. The requirements for marshaling by value and for generic serialization are identical. To marshal an object by value, all .NET has to do is serialize the object to a stream and deserialize the object in the remote app domain. As a result, to enable marshaling by value, the component must be serializable. Serializable components can either use the Serializable attribute or implement the ISerializable interface for custom serialization. For example, consider the following class definition:

    [Serializable]
    public class MyClass
    {
       public int Number;
    }

Suppose an instance of this class has 3 as the value of the Number member and is accessed across an app domain boundary by a remote client. .NET marshals the object by value and gives the remote client a copy of the object. Immediately after marshaling, the cloned object has 3 as the value of the Number member (see Figure 1). When the remote client in App Domain 3 assigns the value 4 to Number, this assignment affects only its own new and distinct copy. Marshaling by value works across any app domain boundary, be it in the same process or across machines.

The primary use for marshaling by value is when you want to pass a structure as a method parameter. Typically, structures are used as data containers and have no logic associated with them. Structures are very useful as method parameters, but unless a struct is serializable, you can't use it as a parameter to a remote call.

When you marshal a struct by value to a remote object, you actually get the same semantics as with a local object because value types are, by default, passed in by value:

					[Serializable]
    public struct MyPoint
    {

Figure 1. Marshaling by value

       public int X;
       public int Y;
    }
      
    public class RemoteClass : MarshalByRefObject
    {
       public void MyMethod(MyPoint point)
       {
          point.X++;
       }
    }

Changes made to the structure on the server side don't affect the structure on the client side:

    //Remote client:
    MyPoint point;
    point.X = 1;
      
    RemoteClass obj = new RemoteClass( );
    obj.MyMethod(point);
    Debug.Assert(point.X == 1);

However, if you pass the structure by reference using the out or ref parameter modifiers, changes made on the remote server side will affect the client's copy of the structure:

    public class RemoteClass : MarshalByRefObject
    {
       public void MyMethod(ref MyPoint point)
       {
          point.X++;
       }
    }
    //Remote client:
    MyPoint point;
    point.X = 1;
      
    RemoteClass obj = new RemoteClass( );
    obj.MyMethod(ref point);
    Debug.Assert(point.X == 2);

This is the same as when you pass a structure by reference in the local case.

The usefulness of marshaling a class instance by value is marginal, because the classic client/server model doesn't fit well with marshaling by value. Marshaling by value for reference types is provided for when the client needs to make frequent calls of short duration to the object, and paying the penalty for marshaling the object state to the client is more efficient than paying the penalty multiple times for marshaling the call to the object and back. Imagine, for example, a distributed image-capturing and processing system. You want the machine capturing the images to do so as fast as it can, and you want the processing to be done on a separate machine. The capturing machine can create an image object, then have the processing client access the object (that would make it copy the image) and process it locally. That said, there is usually a better design solution, such as transferring the image data explicitly as a method parameter. In general, it's often a lot easier to simply marshal a reference to the object to the client and have the client invoke calls on the object via a proxy, as described next.

2. Marshaling by Reference

The second remoting option is marshal by reference, and it's by far the more common way to access objects across app domains. As explained previously, when marshaling by reference is employed, the client accesses the remote object using a proxy . The proxy forwards calls made on it to the actual object. To designate a component for marshaling by reference, the class must derive directly (or have one of its base classes derive) from the class MarshalByRefObject, defined in the System namespace. Objects derived from MarshalByRefObject are bound for life to the app domain in which they were created and can never leave it.

The client has a reference to a proxy, which forwards the call to TraceAppDomain( ) to the new app domain; this is why it traces the remote app domain's name. If the remote object is serializable in addition to being derived from MarshalByRefObject, you can use serialization to persist the object's state, but the object is still accessed by reference. Any static method or member variable on a marshaled-by-reference class is always accessed directly; no proxy is involved, because statics aren't associated with any particular object.

.NET does allow the client app domain and the host app domain to be the same app domain. In that case, the client can still interact with the marshaled-by-reference object using a proxy, even though both share the same app domain. Clients may want to do that in order to activate the object in different ways. However, short-circuiting remoting this way is an esoteric case. In the vast majority of cases, deriving from MarshalByRefObject has no bearing on intra-app domain calls, and clients in the same app domains get direct references to the object.

Other  
  •  Active Directory Domain Services 2008 : Seize the RID Master Role, Seize the PDC Emulator Role, Seize the Infrastructure Master Role
  •  Active Directory Domain Services 2008 : Seize the Schema Master Role, Seize the Domain Naming Master Role
  •  Synology DS212+
  •  QNAP TS-219P II Turbo NAS
  •  Netgear Readynas Duo V2
  •  Iomega Storcenter Ix2 Network Storage Cloud Edition
  •  Freecom Silverstore 2-Drive NAS 2TB
  •  IBM WebSphere Process Server 7 : Installing WID on Windows
  •  IBM WebSphere Process Server 7 : WebSphere Integration Developer overview
  •  D-LINK Sharecenter Shadow DNS-325
  •  Choosing A... NAS Device (Part 2)
  •  Choosing A... NAS Device (Part 1)
  •  Buffalo Linkstation Pro 2TB
  •  Collaborating via Blogs and Wikis : Evaluating Wikis for Collaboration
  •  Collaborating via Blogs and Wikis : Evaluating Blogs for Collaboration
  •  Collaborating via Social Networks and Groupware : Evaluating Online Groupware
  •  Collaborating via Social Networks and Groupware : Creating Groups on Social Networks
  •  Programming .NET Components : Remoting - Application Domains (part 2) - The AppDomain Class, The Host App Domain
  •  Programming .NET Components : Remoting - Application Domains (part 1)
  •  BizTalk 2006 : Managing Exceptions in Orchestrations (part 4) - Processing and Retrieving Messages and Exceptions from the Fault Message
  •  
    Top 10
    What You Can Do With An All-In-One
    Protect Your Business
    Building an Affordable Multi-room Audio System (Part 1)
    Group Test: Integrated Valve Amps $2,175-$3,000 (Part 4)
    Group Test: Integrated Valve Amps $2,175-$3,000 (Part 3)
    Group Test: Integrated Valve Amps $2,175-$3,000 (Part 2)
    Group Test: Integrated Valve Amps $2,175-$3,000 (Part 1)
    Retro Thorens TD 150 - Start It Up (Part 2)
    Retro Thorens TD 150 - Start It Up (Part 1)
    Audio/Video Gear: Models Are Recommended
    Most View
    A Case For Quality (Part 4) - Maroo – Seth Aaron Series: Dotty, ColcaSac – Juan Valdez iPad Sleeve
    SSD Supertest – December 2012 (Part 2) : Intel 330 Series 180GB
    Programming Microsoft SQL Server 2005 : An Overview of SQL CLR - CLR Triggers
    10 ways to save money with your PC
    Dish Network Hopper
    Optimizing for Vertical Search : Optimizing for Product Search
    Group Test: Laptops Running Windows 8 (Part 1) - Asus Zenbook UX32A, HP Envy 4-1020ea, lenovo IdeaPad U410
    SAPPHIRE HD 7850 2GB OverClock Edition
    Motorola Xoom 2 - General Tablet Use
    Search for a File or Directory
    Nikon D600 - A Full-Frame Nikon For Your Full-Time Passion (Part 3)
    Blackberry 10 - Aiming For A Perfect 10
    How To Put Together A Good Home Network (Part 4)
    Hardware Lifecycle Management
    Windows Vista : Setting Up a Small Network - Displaying the Network and Sharing Center, Customizing Your Network
    Windows Mobile Security - Permissions and User Controls
    Windows Server 2008 : The Discovery Phase - Understanding the Existing Environment
    What to Back Up on Exchange Servers 2010
    Silverlight Recipes : Using Sockets to Communicate over TCP (part 3)
    IIS 7.0 : Techniques for Enabling Application Frameworks (part 1) - Enabling New Static File Extensions to Be Served & Deploying Frameworks Based on IIS 7.0 Native Modules