Tải bản đầy đủ - 0 (trang)
3-2. Create Types That Can Be Passed Across Application Domain Boundaries

3-2. Create Types That Can Be Passed Across Application Domain Boundaries

Tải bản đầy đủ - 0trang

CHAPTER 3 ■ APPLICATION DOMAINS, REFLECTION, AND METADATA



Application Domain 2

Object



Proxy



MBR Object



Application Domain 1



Figure 3-1. An MBR object is accessed across application domains via a proxy.



The Code

The following example highlights (in bold) the fundamental difference between creating classes that are

passed by value (Recipe03_02MBV) and those passed by reference (Recipe03_02MBR). The code creates a

new application domain and instantiates two remotable objects in it (discussed further in recipe 3-7).

However, because the Recipe03_02MBV object is an MBV object, when it is created in the new application

domain, it is serialized, passed across the application domain boundary, and deserialized as a new

independent object in the caller’s application domain. Therefore, when the code retrieves the name of

the application domain hosting each object, Recipe03_02MBV returns the name of the main application

domain, and Recipe03_02MBR returns the name of the new application domain in which it was created.

using System;

namespace Apress.VisualCSharpRecipes.Chapter03

{

// Declare a class that is passed by value.

[Serializable]

public class Recipe03_02MBV

{



107



www.it-ebooks.info



CHAPTER 3 ■ APPLICATION DOMAINS, REFLECTION, AND METADATA



public string HomeAppDomain

{

get

{

return AppDomain.CurrentDomain.FriendlyName;

}

}

}

// Declare a class that is passed by reference.

public class Recipe03_02MBR: MarshalByRefObject

{

public string HomeAppDomain

{

get

{

return AppDomain.CurrentDomain.FriendlyName;

}

}

}

public class Recipe03_02

{

public static void Main(string[] args)

{

// Create a new application domain.

AppDomain newDomain =

AppDomain.CreateDomain("My New AppDomain");

// Instantiate an MBV object in the new application domain.

Recipe03_02MBV mbvObject =

(Recipe03_02MBV)newDomain.CreateInstanceFromAndUnwrap(

"Recipe03-02.exe",

"Apress.VisualCSharpRecipes.Chapter03.Recipe03_02MBV");

// Instantiate an MBR object in the new application domain.

Recipe03_02MBR mbrObject =

(Recipe03_02MBR)newDomain.CreateInstanceFromAndUnwrap(

"Recipe03-02.exe",

"Apress.VisualCSharpRecipes.Chapter03.Recipe03_02MBR");

// Display the name of the application domain in which each of

// the objects is located.

Console.WriteLine("Main AppDomain = {0}",

AppDomain.CurrentDomain.FriendlyName);

Console.WriteLine("AppDomain of MBV object = {0}",

mbvObject.HomeAppDomain);

Console.WriteLine("AppDomain of MBR object = {0}",

mbrObject.HomeAppDomain);



108



www.it-ebooks.info



CHAPTER 3 ■ APPLICATION DOMAINS, REFLECTION, AND METADATA



// Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter.");

Console.ReadLine();

}

}

}



■ Note Recipe 13-1 provides more details on creating serializable types, and recipe 10-16 describes how to

create remotable types.



3-3. Avoid Loading Unnecessary Assemblies into Application

Domains

Problem

You need to pass an object reference across multiple application domain boundaries; however, to

conserve memory and avoid impacting performance, you want to ensure that the Common Language

Runtime (CLR) loads only the object’s type metadata into the application domains where it is required

(that is, where you will actually use the object).



Solution

Wrap the object reference in a System.Runtime.Remoting.ObjectHandle, and unwrap the object reference

only when you need to access the object.



How It Works

When you pass an MBV object across application domain boundaries, the runtime creates a new

instance of that object in the destination application domain. This means the runtime must load the

assembly containing that type metadata into the application domain. Passing MBV references across

intermediate application domains can result in the runtime loading unnecessary assemblies into

application domains. Once loaded, these superfluous assemblies cannot be unloaded without unloading

the containing application domain. (See recipe 3-9 for more information.)

The ObjectHandle class allows you to wrap an object reference so that you can pass it between

application domains without the runtime loading additional assemblies. When the object reaches the

destination application domain, you can unwrap the object reference, causing the runtime to load the

required assembly and allowing you to access the object as usual.



109



www.it-ebooks.info



CHAPTER 3 ■ APPLICATION DOMAINS, REFLECTION, AND METADATA



The Code

The following code contains some simple methods that demonstrate how to wrap and unwrap a

System.Data.DataSet using an ObjectHandle:

using System;

using System.Data;

using System.Runtime.Remoting;

namespace Apress.VisualCSharpRecipes.Chapter03

{

class Recipe03_03

{

// A method to wrap a DataSet.

public static ObjectHandle WrapDataSet(DataSet ds)

{

// Wrap the DataSet.

ObjectHandle objHandle = new ObjectHandle(ds);

// Return the wrapped DataSet.

return objHandle;

}

// A method to unwrap a DataSet.

public static DataSet UnwrapDataSet(ObjectHandle handle)

{

// Unwrap the DataSet.

DataSet ds = (System.Data.DataSet)handle.Unwrap();

// Return the wrapped DataSet.

return ds;

}

public static void Main()

{

DataSet ds = new DataSet();

Console.WriteLine(ds.ToString());

ObjectHandle oh = WrapDataSet(ds);

DataSet ds2 = UnwrapDataSet(oh);

Console.WriteLine(ds2.ToString());

// Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter.");

Console.ReadLine();

}

}

}



110



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

3-2. Create Types That Can Be Passed Across Application Domain Boundaries

Tải bản đầy đủ ngay(0 tr)

×