public void MakeSerializable(MutableType proxyType, MethodInfo initializationMethod) { ArgumentUtility.CheckNotNull("proxyType", proxyType); // initializationMethod may be null // Base fields are always serialized by the standard .NET serialization or by an implementation of ISerializable on the base type. // Added fields are also serialized by the standard .NET serialization, unless the proxy type implements ISerializable. In that case, // we need to extend the ISerializable implementation to include the added fields. var serializedFieldMapping = _serializableFieldFinder.GetSerializableFieldMapping(proxyType.AddedFields.Cast <FieldInfo>()).ToArray(); var deserializationConstructor = GetDeserializationConstructor(proxyType); // If the base type implements ISerializable but has no deserialization constructor, we can't implement ISerializable correctly, so // we don't even try. (ComplexSerializationEnabler relies on this behavior.) var needsCustomFieldSerialization = serializedFieldMapping.Length != 0 && typeof(ISerializable).IsTypePipeAssignableFrom(proxyType) && deserializationConstructor != null; if (needsCustomFieldSerialization) { OverrideGetObjectData(proxyType, serializedFieldMapping); AdaptDeserializationConstructor(deserializationConstructor, serializedFieldMapping); } if (initializationMethod != null) { if (typeof(IDeserializationCallback).IsTypePipeAssignableFrom(proxyType)) { OverrideOnDeserialization(proxyType, initializationMethod); } else if (proxyType.IsTypePipeSerializable()) { ExplicitlyImplementOnDeserialization(proxyType, initializationMethod); } } }
public void MakeSerializable( MutableType proxyType, string participantConfigurationID, IAssembledTypeIdentifierProvider assembledTypeIdentifierProvider, AssembledTypeID typeID) { ArgumentUtility.CheckNotNull("proxyType", proxyType); ArgumentUtility.CheckNotNullOrEmpty("participantConfigurationID", participantConfigurationID); ArgumentUtility.CheckNotNull("assembledTypeIdentifierProvider", assembledTypeIdentifierProvider); if (!proxyType.IsTypePipeSerializable()) { return; } var assembledTypeIDData = assembledTypeIdentifierProvider.GetAssembledTypeIDDataExpression(typeID); if (typeof(ISerializable).IsTypePipeAssignableFrom(proxyType)) { // If the mutable type already implements ISerializable, we only need to extend the implementation to include the metadata required for // deserialization. Existing fields will be serialized by the base ISerialization implementation. Added fields will be serialized by // the TypePipe (ProxySerializationEnabler). try { proxyType .GetOrAddImplementation(s_getObjectDataMethod) .SetBody( ctx => Expression.Block( ctx.PreviousBody, CreateMetaDataSerializationExpression( ctx.Parameters[0], typeof(ObjectWithDeserializationConstructorProxy), participantConfigurationID, assembledTypeIDData))); } catch (NotSupportedException) { // Overriding and re-implementation failed because the base implementation of GetObjectData is not accessible from the proxy. // Do nothing here; error reporting code will be generated in the ProxySerializationEnabler. // Reasoning: Users often cannot influence the requested type and do not care about any serialization problem. } } else { // If the mutable type does not implement ISerializable, we need to add the interface and then also serialize all the fields on the object. // We cannot add a deserialization constructor because there is no base constructor that we could call. Therefore, ProxySerializationEnabler // cannot take care of serializing the added fields, and we thus have to serialize both existing and added fields ourselves via // ReflectionSerializationHelper.AddFieldValues. proxyType.AddInterface(typeof(ISerializable)); proxyType.AddExplicitOverride( s_getObjectDataMethod, ctx => Expression.Block( CreateMetaDataSerializationExpression( ctx.Parameters[0], typeof(ObjectWithoutDeserializationConstructorProxy), participantConfigurationID, assembledTypeIDData), Expression.Call(s_addFieldValuesMethod, ctx.Parameters[0], ctx.This))); } }