Google
 

Monday, June 04, 2007

What is and why MarshalByRefObject ?

REF: MSDN
Enables access to objects across application domain boundaries in applications that support remoting.

Namespace: System
Assembly: mscorlib (in mscorlib.dll)

Remarks
Sample 1
The following code example shows the simplest way to execute code in another application domain. The example defines a class named Worker that inherits MarshalByRefObject, with a method that displays the name of the application domain in which it is executing. The example creates instances of Worker in the default application domain and in a new application domain.
Note:The assembly that contains Worker must be loaded into both application domains, but it could load other assemblies that would exist only in the new application domain.

using System;
using System.Reflection;

//namespace TestingMarshalObject
//{

public class Worker : MarshalByRefObject
{
public void PrintDomain(){
Console.WriteLine(
"Object is executing in AppDomain \"{0}\"",
AppDomain.CurrentDomain.FriendlyName);
}
}

public class Example
{
/* This code produces output similar to the following:

Object is executing in AppDomain "source.exe"
Object is executing in AppDomain "New domain"
*/
public static void Main(){
// Create an ordinary instance in the current AppDomain
Worker localWorker = new Worker();
localWorker.PrintDomain();

// Create a new application domain, create an instance
// of Worker in the application domain, and execute code
// there.

// Note: The example and Worker can not be in the same namespace
// If so the following code will throw exception:
//Could not load type 'Worker' from assembly 'TestingMarshalObject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

AppDomain ad
= AppDomain.CreateDomain("New domain");
Worker remoteWorker
= (Worker) ad.CreateInstanceAndUnwrap(
typeof(Worker).Assembly.FullName,
typeof(Worker).Name);
remoteWorker.PrintDomain();

Console.Read();
}
}
//}



Sample 2
The following example demonstrates a class derived from MarshalByRefObject that is used later in remoting.

using System;
using System.Runtime.Remoting;
using System.Security.Permissions;

public class SetObjectUriForMarshalTest
{

class TestClass : MarshalByRefObject
{
}

[SecurityPermission(SecurityAction.LinkDemand)]
public static void Main()
{

TestClass obj
= new TestClass();

RemotingServices.SetObjectUriForMarshal(obj,
"testUri");
RemotingServices.Marshal(obj);

Console.WriteLine(RemotingServices.GetObjectUri(obj));

Console.Read();
}
}

Inheriting from MarshalByRefObject

Developers often wonder why they are forced to derive from MarshalByRefObject or EnterpriseServices.ServicedComponent. It would be so much more convenient if they could add a CustomAttribute to their class or use a marker interface to declare that they want to be marshaled by reference or they want serviced behavior.

The reason has to do with performance. The CLR has a large number of optimizations which it can apply to objects that are guaranteed to be local. If the object is possibly remote, then these optimizations are invalidated. Examples include method inlining by the JIT, direct field access, fast instantiation in the local heap, direct method invocation for non-virtuals and more efficient type tests like cast operations.

When the benefit of these optimizations is considered, it completely outweighs the programming model impact to the inheritance hierarchy. This decision is key to achieving our long term goal of performance parity with native code.


REF: http://blogs.msdn.com/cbrumme/archive/2003/04/15/51340.aspx

No comments: