Marshaling and Remoting The days of integrated programs all running in a single process on a single machine are, if not dead, at least seriously wounded. Today’s programs consist of complex components running in multiple processes, often across the network. The Web has facilitated distributed applications in a way that was unthinkable even a few years ago, and the trend is toward distribution of responsibility. A second trend is toward centralizing business logic on large servers. Although these trends appear to be contradictory, in fact they are synergistic: business objects are being centralized while the user interface and even some middleware are being distributed. The net effect is that objects need to be able to talk with one another at a distance. Objects running on a server handling the web user interface need to be able to interact with business objects living on centralized servers at corporate headquarters. The process of moving an object across a boundary is called remoting. Boundaries exist at various levels of abstraction in your program. The most obvious boundary is between objects running on different machines. The process of preparing an object to be remoted is called marshaling. Marshaling is accomplished in two ways: by value or by reference. On a single machine, objects might need to be marshaled across context, app domain, or process boundaries. A process is essentially a running application. If an object in your word processor wants to interact with an object in your spreadsheet, they must communicate across process boundaries. Processes are divided into application domains (often called “app domains”); these in turn are divided into various contexts. App domains act like lightweight processes, and contexts create boundaries that objects with similar rules can be contained within. At times, objects will be marshaled across both context and app domain boundaries, as well as across process and machine boundaries. A sink is an object whose job is to enforce policy. Formatter When an object is remoted, it appears to be sent through the wire from one computer to another, much like teleported, but in the .NET edition it is all an illusion. The actual transmission of the message is done by a channel. The channel’s job is to know how to move the message. The channel works with a formatter. The formatter makes sure the message is in the right format. The formatter can translate your message into a right format which can be understand by the remote system. The formatter is silently facilitating the communication. Application Domains A process is, essentially, a running application. Each .NET application runs in its own process. For example, If you have Word, Excel, and Visual Studio open, you have three processes running. If you open another copy of Word, another process starts up. Each process is subdivided into one or more application domains (or app domains). An app domain acts like a process but uses fewer resources. App domains can be independently started and halted; they are secure, lightweight, and versatile. An app domain can provide fault tolerance; if an object is started in a second app domain and it crashes, it will bring down the app domain but not the entire program. Web servers might use app domains for running users’ code; if the code has a problem, the web server can maintain operations. An app domain is encapsulated by an instance of the AppDomain class, which offers a number of methods and properties. Application domain context: Context App domains themselves are subdivided into contexts. Contexts can be thought of as boundaries within which objects share usage rules. These usage rules include synchronization transactions, and so forth. Context-Bound and Context-Agile Objects Objects are either context-bound or they are context-agile. If they are context-bound, they exist in a context, and to interact with them the message must be marshaled. If they are context-agile, they act within the context of the calling object; that is, their methods execute in the context of the object that invokes the method and so marshaling is not required. Suppose you have an object A that interacts with the database and so is marked to support An object thus has three choices. o Context-agile. A context-agile object operates in the context of its caller. o Context-bound accomplished by deriving from ContextBoundObject but have no attributes, and thus operate in the context of the creator. o Context-bound with context attributes, and thus operate only in the context that matches the attributes. If your object is a simple calculator that cannot possibly need synchronization or transactions or any context support, it is more efficient to be context-agile. If your object should use the context of the object that creates it, you should make that object context-bound with no attributes. Finally, if your object has its own context requirements, you should give it the appropriate attributes. Fig. Shows working model of Context-Agile: Fig. Shows working model of Context-bound objects: Marshaling Across Context Boundaries No proxy is needed when accessing context-agile objects within a single app domain. When an object in one context accesses a context-bound object in a second context, it does so through a proxy, and at that time the two context policies are enforced. It is in this sense that a context creates a boundary; the policy is enforced at the boundary between contexts. All objects outside that context must pass through the context boundary to touch one of the objects, and at that time the policy of synchronization will be applied.