Remoting Boundaries

Remoting Boundaries

In the unmanaged world, the Microsoft Windows operating system segregates applications into separate processes. In essence, the process forms a boundary around application code and data. All data and memory addresses are process relative, and code executing in one process can t access memory in another process without using some sort of interprocess communication (IPC) mechanism. One benefit of this address isolation is a more fault-tolerant environment because a fault occurring in one process doesn t affect other processes. Address isolation also prevents code in one process from directly manipulating data in another process.

Because the common language runtime verifies managed code as type-safe and verifies that the managed code does not access invalid memory locations, the runtime can run multiple applications within a single process and still provide the same isolation benefits as the unmanaged application-per-process model. The common language runtime defines two logical subdivisions for .NET applications: the application domain and the context.

Application Domains

You can think of the application domain as a logical process. We say this because it s possible for a single Win32 process to contain more than one application domain. Code and objects executing in one application domain can t directly access code and objects executing in another application domain. This provides a level of protection because a fault occurring in one application domain won t affect other application domains within the process. The division between application domains forms a .NET Remoting boundary.

Contexts

The common language runtime further subdivides an application domain into contexts. A context guarantees that a common set of constraints and usage semantics will govern all access to the objects within it. For example, a synchronization context might allow only one thread to execute within the context at a time. This means objects within the synchronization context don t have to provide extra synchronization code to handle concurrency issues. Every application domain contains at least one context, known as the default context. Unless an object explicitly requires a specialized context, the runtime will create that object in the default context. We ll discuss the mechanics of contexts in detail in Chapter 6, Message Sinks and Contexts. For now, realize that, as with application domains, the division between contexts forms a .NET Remoting boundary.

Crossing the Boundaries

.NET Remoting enables objects executing within the logical subdivisions of application domains and contexts to interact with one another across .NET Remoting boundaries. A .NET Remoting boundary acts like a semipermeable membrane: in some cases, it allows an instance of a type to pass through unchanged; in other cases, the membrane allows an object instance outside the application domain or context to interact with the contained instance only through a well-defined protocol or not at all.

The .NET Remoting infrastructure splits objects into two categories: nonremotable and remotable. A type is remotable if and only if at least one of the following conditions holds true:

  • Instances of the type can cross .NET Remoting boundaries.

  • Other objects can access instances of the type across .NET Remoting boundaries.

Conversely, if a type doesn t exhibit either of these qualities, that type is nonremotable.

Nonremotable Types

Not every type is remotable. Instances of a nonremotable type can t cross a .NET Remoting boundary, period. If you attempt to pass an instance of a nonremotable type to another application domain or context, the .NET Remoting infrastructure will throw an exception. Furthermore, object instances residing outside an application domain or a context containing an object instance of a nonremotable type can t directly access that instance.

Remotable Types

Depending on its category, a remotable type can pass through .NET Remoting boundaries or be accessed over .NET Remoting boundaries. .NET Remoting defines three categories of remotable types: marshal-by-value, marshal-by-reference, and context-bound.

Marshal-by-Value

Instances of marshal-by-value types can cross .NET Remoting boundaries through a process known as serialization. Serialization is the act of encoding the present state of an object into a sequence of bits. Once the object has been serialized, the .NET Remoting infrastructure transfers the sequence of bits across .NET Remoting boundaries into another application domain or context where the infrastructure then deserializes the sequence of bits into an instance of the type containing an exact copy of the state. In .NET, a type is serializable if it is declared by using the Serializable attribute. The following code snippet declares a class that s made serializable by using the Serializable attribute:

[Serializable] class SomeSerializableClass {   }

In addition, a Serializable-attributed type can implement the ISerializable interface to perform custom serialization. We ll discuss serialization in detail in Chapter 8. Figure 2-1 shows the serialization and deserialization of an object instance from one application domain to another application domain.

figure 2-1 marshal-by-value: object instance serialized from one application domain to another

Figure 2-1. Marshal-by-value: object instance serialized from one application domain to another

Marshal-by-Reference

Marshal-by-value is fine for some circumstances, but sometimes you want to create an instance of a type in an application domain and know that all access to such an object will occur on the object instance in that application domain rather than on a copy of it in another application domain. For example, an object instance might require resources that are available only to object instances executing on a specific machine. In this case, we refer to such types as marshal-by-reference, because the .NET Remoting infrastructure marshals a reference to the object instance rather than serializing a copy of the object instance. To define a marshal-by-reference type, the .NET Framework requires that you derive from System.MarshalByRefObject. Simply deriving from this class enables instances of the type to be remotely accessible. The following code snippet shows an example of a marshal-by-reference type:

class SomeMBRType : MarshalByRefObject {   }

Figure 2-2 shows how a marshal-by-reference remote object instance remains in its home application domain and interacts with object instances outside the home application domain through the .NET Remoting infrastructure.

figure 2-2 marshal-by-reference: object instance remains in its home application domain

Figure 2-2. Marshal-by-reference: object instance remains in its home application domain

Context-Bound

A further refinement of marshal-by-reference is the context-bound type. Deriving a type from System.ContextBoundObject will restrict instances of such a type to remaining within a specific context. Objects external to the containing context can t directly access ContextBoundObject types, even if the other objects are within the same application domain. We ll discuss context-bound types in detail in Chapter 6, Message Sinks and Contexts. The following code snippet declares a context-bound type:

class SomeContextBoundType : ContextBoundObject {   }

Figure 2-3 shows the interactions between a Context-Bound object and other objects outside its context.

figure 2-3 context-bound: remote objects bound to a context interact with objects outside the context through the .net remoting infrastructure

Figure 2-3. Context-bound: remote objects bound to a context interact with objects outside the context through the .NET Remoting infrastructure



Microsoft. NET Remoting
Microsoft .NET Remoting (Pro-Developer)
ISBN: 0735617783
EAN: 2147483647
Year: 2005
Pages: 46

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net