As mentioned earlier, there are many destinations for a serialized set of objects: same process, dif- ferent process on the same machine, different process on a different machine, and so on. In some rare situations, an object might want to know where it is going to be deserialized so that it can emit its state differently. For example, an object that wraps a Windows semaphore object might decide to serialize its kernel handle if the object knows that it will be deserialized into the same process, because kernel handles are valid within a process. However, the object might decide to serialize the
semaphore’s string name if it knows that the object will be deserialized on the same machine but into a different process. Finally, the object might decide to throw an exception if it knows that it will be deserialized in a process running on a different machine because a semaphore is valid only within a single machine.
A number of the methods mentioned earlier in this chapter accept a StreamingContext. A StreamingContext structure is a very simple value type offering just two public read-only proper- ties, as shown in Table 24-1.
TABLE 24-1StreamingContext’s Public Read-Only Properties
Member Name
Member Type
Description
State
StreamingContextStates
A set of bit flags indicating the source or destination of the
objects being serialized/deserialized
Context
Object
A reference to an object that contains any user-desired context information
A method that receives a StreamingContext structure can examine the State property’s bit flags to determine the source or destination of the objects being serialized/deserialized. Table 24-2 shows the possible bit flag values.
TABLE 24-2StreamingContextStates’s Flags
Flag Name
Flag Value
Description
CrossProcess
0x0001
The source or destination is a different process on the same machine.
CrossMachines
0x0002
The source or destination is on a different machine.
File
0x0004
The source or destination is a file. Don’t assume that the same
process will deserialize the data.
Persistence
0x0008
The source or destination is a store such as a database or a file.
Don’t assume that the same process will deserialize the data.
Remoting
0x0010
The source or destination is remoting to an unknown location. The location may be on the same machine but may also be on another machine.
Other
0x0020
The source or destination is unknown.
Clone
0x0040
The object graph is being cloned. The serialization code may as- sume that the same process will deserialize the data, and it is therefore safe to access handles or other unmanaged resources.
CrossAppDomain
0x0080
The source or destination is a different AppDomain.
All
0x00FF
The source or destination may be any of the above contexts. This is the default context.
Now that you know how to get this information, let’s discuss how you would set this information.
The IFormatter interface (which is implemented by both the BinaryFormatter and the Soap Formatter types) defines a read/write StreamingContext property called Context. When you construct a formatter, the formatter initializes its Context property so that StreamingContext States is set to All and the reference to the additional state object is set to null.
After the formatter is constructed, you can construct a StreamingContext structure using any of the StreamingContextStates bit flags, and you can optionally pass a reference to an object containing any additional context information you need. Now, all you need to do is set the format- ter’s Context property with this new StreamingContext object before calling the formatter’s Serialize or Deserialize methods. Code demonstrating how to tell a formatter that you are serializing/deserialzing an object graph for the sole purpose of cloning all the objects in the graph is shown in the DeepClone method presented earlier in this chapter.