BizTalk Utilities CV ,   Jobs ,   Code library  
 
Home Page
XmlSerializer
ISerializable
Streaming Context States
Custom Serialization
IXmlSerializable
DataSet Object
Namespace at runtime
XmlSerializer Namespaces
Serialization Namespaces
Event notifications
Serializing Objects
any and anyAttribute
XmlAnyElement
Serializing XML nodes
Choice Model Groups
Generic XmlSerializer
Runtime Overrides
Runtime Customization
Customizing Xml Serialization
Advanced XmlSerializer
XmlSerializer Attributes
<< XML DOM
XQuery >>

By :Mark Wilson
I am the creator of TopXML. I am available for international and local (Australia) contracts. I am a Solution Architect/Business Analyst. I have worked in IT in several countries (NZ, Australia, South Africa, UK) building and training teams for government and very large non-governmental organizations. I am ex-Microsoft Consulting Services. I wrote the first book on Microsoft XML published in 2000 called XML Programming with VB and ASP. Most recently I have been building tools for the SEO industry. Ask me for a 37 point SEO health-checkup for your website.
First posted :03/24/2008
Times viewed :1432

 

Surrogate Selectors

Section 12.2.2 demonstrated techniques how we can serialize objects that are not marked serializable. We can either derive a new class that implements the ISerializable interface or, if the class does not allow us to derive from it, we can wrap it in a new class that will handle serialization. Both techniques have their drawbacks. Maybe we cannot replace a class with a different class everywhere it is referenced and wrapping an object does not only introduce a completely unrelated type it also is pretty cumbersome.

Implementing SerializationSurrogates

The .NET Framework provides one more hook to customize object serialization that allows full customization if the whole serialization process and is completely transparent to the serialized objects. This solution requires a little bit more coding than implementing the ISerializable interface, but it will allow us to control serialization (and deserialization) for every class in the system, regardless if it is marked Serializable. The trick is to reroute the whole serialization process to a different class, the serialization surrogate. This class has to implement the ISerializationSurrogate interface, which is similar in nature to the ISerializable interface. Table 12.7 shows the methods defined by the ISerializationSurrogate interface and their semantics.

1.10         Table 12.7 A serialization surrogate takes over serialization for all instances of a certain class. The surrogate has to implement the ISerializationSurrogate interface with these methods.

Method

Description

void GetObjectData(

   object obj,

   SerializationInfo info,

   StreamingContext context

);

Fills the SerializationInfo info  with the data to serialize the object obj. The StreamingContext contains information to tune the serialized data to the intended deserialization scenario.

object SetObjectData(

   object obj,

   SerializationInfo info,

   StreamingContext context,

   ISurrogateSelector selector

);

Retrieves data to deserialize the object obj from the SerializationInfo info . The StreamingContext contains information to identify source context of the serialized data. The selector parameter supplies the SurrogateSelector chain registered with this formatter.

The GetObjectData() and SetObjectData() methods perform the same functionality as GetObjectData() on the ISerializable interface and the deserialization constructor. The difference is that these methods are not implemented on the object that is serialized or deserialized. The parameters of both methods are identical to their counterparts in the ISerializable implementations. The SerializationInfo object serves as a container for the serialized information and the StreamingContext provides details about the context in which the operation executes. We already discussed these two classes in more detail in the previous section, now we can focus implementing ISerializationSurrogate.

Because ISerializationSurrogate is not implemented on the serialized object directly the SetObjectData() and GetObjectData() methods only have access to public fields and properties. In many cases the public fields provide enough information to recreate objects later on. However, SetObjectData() will receive a fresh, completely un-initialized object that was created without(!) running any constructors. Likewise, no variable-initializers were executed when this object is created, all fields are set to null when the object is passed to SetObjectData(). You can probably imagine the catastrophic effects an uninitialized private field can have on the behavior of an object.

WARNING: We must exercise extreme caution and thoroughly test to ensure deserialized objects are fully functional if we implement surrogates for 3rd party classes that do not persist all fields.

Now, there is a way to read and set private fields, but it is only available in fully trusted environments. Just as the runtime formatters, we can access private members through reflection. In order to do so our applications require all security privileges related to reflection. Also the penalty for accessing fields through reflection is very stiff, easily greater than 100x compared to assignments through writable properties, for example. However, by setting each member during deserialization we can guarantee an object will behave just like the one serialized.

Registering Serialization Surrogates

We have to register the surrogate with a formatter if we want the formatter to channel serialization for certain classes through our surrogates rather than checking the object for ISerializable or handling the class itself. However, the registration is managed by a surrogate selector, not by the formatter itself. The selector is a special container to register surrogates by type and serialization context. Yes, you can register different surrogates for different scenarios, e.g. one for long term object persistence in files and one to transmit objects across process boundaries on the same machine. This gives us the same flexibility for optimizing the serialization process as we have with the ISerializable interface. Furthermore, it allows very fine grained control over the scenarios in which we want to override a class’ built-in serialization because we do not have to register a surrogate for all possible contexts. The scenarios are also identified by a StreamingContext object with the semantics we discussed in section 12.2 and table 12.3.

To register one or more selectors, the formatter exposes a property named SurrogateSelector. With surrogate selectors registered, the formatter iterates over all selectors to find a surrogate for the object type it has to process in the given context. If it can locate an appropriate surrogate it delegates serialization to the surrogate. Figure 12.1 illustrates this interaction between the formatter, the surrogate selector and the serialization surrogate.

Figure 12.1 Several objects collaborate when we delegate serialization to a surrogate serializer: An application registers a surrogate for a certain class with a surrogate selector. Every time a serialization formatter reads or writes an object, it checks with the surrogate selector if any surrogates are available for the given class in the current context. If the surrogate can provide a surrogate, all serialization activity as delegated to the surrogate.

A surrogate selector object has to implement the ISurrogateSelector interface (table 12.8) to interact with the runtime serialization formatters of the .NET Framework. The interface defines the GetSurrogate() method to retrieve serialization surrogates by object type and serialization scenario.

1.11         Table 12.8 Serialization formatters communicate with surrogate selectors over the ISurrogateSelector interface. The interface allows

Method

Description

public virtual void ChainSelector(

   ISurrogateSelectorselector

);

Adds a selector object to the chain of selector objects

public virtual ISurrogateSelector GetNextSelector();

Returns the next surrogate selector in the chain of selector objects.

public virtual ISerializationSurrogate GetSurrogate(

   Typetype,

   StreamingContextcontext,

   out ISurrogateSelectorselector

);

Locate a surrogate for type and context in the chain of selector objects. The selector parameter references the surrogate selector containing the matching surrogate when the method returns.

The interface defines two additional methods, one to allow chaining multiple selector objects and one to enable the serialization formatter to traverse the chain. The interface does not define any methods to add surrogates to the selector’s selection, but since the interface only defines the interaction between the serialization formatter and the surrogate selector a firm definition of this method is not required.

Now that you know how the ISurrogateSelector interface works, I can tell you rarely have to implement it because the .NET Framework already supplies a default implementation ready for us to use with the SurrogateSelector class. In addition to the methods mandated by the ISurrogateSelector interface this class also exposes the two methods shown in table 12.9 to add and remove surrogate objects.

1.12         Table 12.9 The SurrogateSelector class exposes methods to manage the contained serialization surrogates

Method

Description

public virtual void AddSurrogate(

   Typetype,

   StreamingContextcontext,

   ISerializationSurrogatesurrogate

);

Adds the surrogate to use for an object of type type in the context specified by context to the slection.

public virtual void RemoveSurrogate(

   Typetype,

   StreamingContextcontext

 

Removes the surrogate for objects of type type and the context specified by context from the selection.


Rate this article on a scale of 1 to 10

Your vote :  


 

Recent Jobs

Integration Specialist Needed - Wor
Virtualization Server Infrastructur
A great opportunity to Digital Vide
here is a greate opportunity as a S
A great opportunity as a Network En

View all Jobs (Add yours)
View all CV (Add yours)



Information Online

swimming pool builder
chicago web site design
conference call for CA
Domain Names
it outsourcing
Emporio armani sunglasses
answering service


    Email TopXML  

Front Page Daily Stuff TopXML Forum XML blogs XML Newsgroups BizTalk Biztalk Utilities Biztalk Utilities Tutorial B2B SAP XML Microsoft .NET Dotnet System XML Soapformatter SQLXML XMLserializer XQuery PHP PHP SimpleXML PHP XML Dom PHP XML RPC PHP XSLT Java Java Java XML Xalan Microsoft ASP ASP Schemas XML SQL Server XML XMLDom XSL XSL Tutorial XSLT Stylesheets General Javascript CSS XHTML WAP