[Mono-dev] Re: Serialization strategies for compatibility.

Robert Jordan robertj at gmx.net
Mon Jun 5 07:35:42 EDT 2006


Hi,

>     These particular hooks would allow us to implement a fast "Color",
> for instance, we can use the [OnDeserialized] attribute and compute the
> ARGB values as soon as the type has been de-serialized, avoiding
> completely the ugly test that we currently have in place.
> 
>     Now, there are two problems:
> 
> 	* It is only available in 2.0.

I've implemented 2.0 serialization a couple of days ago. It still
needs some unit tests and a complete interoperatibility test.
I'll finish them by the end of the week, if I'll not discover
that the reflective approach of calling the new hooks is
too slow ... (see below).

> 
> 	* The new hooks do not cope well with differently-named fields.

Indeed, it's a bit clumsy:

[NonSerialized] type monoFieldName;
                 type msnetFieldName;

[OnSerializing]
void Serialize (StreamingContext context)
{
     msnetFieldName = monoFieldName;
}

[OnDeserialized]
void Deserialize (StreamingContext context)
{
     monoFieldName = msnetFieldName;
}


>     Since this stuff is genuinely useful, I was considering whether we
> could make our 1.1 implementation support it, but to avoid exposing a
> non-existent 1.1 type, we could do a name-based attribute lookup on the
> methods and if we find that there is such an attribute, we could perform
> the same tasks that 2.0 does.   This means that 1.1 assemblies could get
> the 2.0 "hooks" by including their own copy of the attribute.   The only
> issue here is whether this would not have a negative performance
> impact.  

The additional performance loss can be neglected, because it's probably
bad enough already:

// 2.0
foreach (MethodInfo mi in type.GetMethods (...)) {
     if (params match StreamingContext)
         methodInfo.GetCustomAttributes (
             typeof (OnDeserializedAttribute))
         cache the MethodInfo
}

vs.

// 1.0
foreach (MethodInfo mi in type.GetMethods (...)) {
     if (params match StreamingContext)
         foreach (Attribute a in mi.GetCustomAttributes ()) {
             if (a.FullName.EndsWith (".OnDeserializedAttribute")) ...
                 cache the MethodInfo
}

which must be done only once per type.

I guess a code generator will be necessary to optimize this.


>     The second issue is: how do we cope with deserialization in the
> future without having to change our internals extensively?   And I think
> that if we extend the serialization framework we can do this.
> 
>     We could introduce some *extra* attributes that are specific to
> Mono, and that are applied to the type.  If such attribute is found, it
> would instruct the deserializer to not perform the manual
> deserialization/serialization, but instead use an ISerializable-like
> approach on that given class, this would give us the control we need.
> 
>     Now in .NET 1.1 SP-N I noticed that they introduced some changes.
> Some classes now implemented some new interfaces that were not present
> in .NET 1.1.   My question is: what is the justification to add new
> implemented interfaces to classes, and could we get away by just
> sprinkling "ISerializable" on our classes, or would that be considered a
> massive breach of API compatibility?    

I'd go for an extra attribute that could be attached on
the type (like [Serialized]), and that expects the same
semantics like ISerializable (method GetObjectData and
.ctor(SerializationInfo, StreamingContext)).


My concern with those solutions is: how do they fit
in the CAS? Are there some hidden security implications?

Robert




More information about the Mono-devel-list mailing list