private void OverrideGetObjectData(MutableType proxyType, Tuple <string, FieldInfo>[] serializedFieldMapping) { try { proxyType .GetOrAddImplementation(s_getObjectDataMethod) .SetBody( ctx => Expression.Block( typeof(void), new[] { ctx.PreviousBody }.Concat(BuildFieldSerializationExpressions(ctx.This, ctx.Parameters[0], serializedFieldMapping)))); } catch (NotSupportedException) { // Overriding and re-implementation failed because the base implementation is not accessible from the proxy. // Do nothing here; error reporting code will be generated in the ProxySerializationEnabler. // Add an explicit re-implementation that throws exception (instead of simply throwing an exception here). // Reasoning: Users often cannot influence the requested type and do not care about any serialization problem. proxyType.AddInterface(typeof(ISerializable), throwIfAlreadyImplemented: false); var message = "The requested type implements ISerializable but GetObjectData is not accessible from the proxy. " + "Make sure that GetObjectData is implemented implicitly (not explicitly)."; proxyType.AddExplicitOverride( s_getObjectDataMethod, ctx => Expression.Throw(Expression.New(s_serializationExceptionConstructor, Expression.Constant(message)))); } }
private void OverrideOnDeserialization(MutableType proxyType, MethodInfo initializationMethod) { try { proxyType.GetOrAddImplementation(s_onDeserializationMethod) .SetBody( ctx => Expression.Block( typeof(void), ctx.PreviousBody, CallInitializationMethod(ctx.This, initializationMethod))); } catch (NotSupportedException) { // Overriding and re-implementation failed because the base implementation is not accessible from the proxy. // Add an explicit re-implementation that throws exception (instead of simply throwing an exception here). // Reasoning: Users often cannot influence the requested type and do not care about any serialization problem. proxyType.AddInterface(typeof(IDeserializationCallback), throwIfAlreadyImplemented: false); var message = "The requested type implements IDeserializationCallback but OnDeserialization is not accessible from the proxy. " + "Make sure that OnDeserialization is implemented implicitly (not explicitly)."; proxyType.AddExplicitOverride( s_onDeserializationMethod, ctx => Expression.Throw(Expression.New(s_serializationExceptionConstructor, Expression.Constant(message)))); } }
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))); } }
private MutableMethodInfo ImplementIntroducedMethod( Expression implementer, MethodInfo interfaceMethod, MethodDefinition implementingMethod, MemberVisibility visibility) { var method = visibility == MemberVisibility.Public ? _concreteTarget.GetOrAddImplementation(interfaceMethod) : _concreteTarget.AddExplicitOverride(interfaceMethod, ctx => Expression.Default(ctx.ReturnType)); method.SetBody(ctx => _expressionBuilder.CreateInitializingDelegation(ctx, _initializationMethod, implementer, interfaceMethod)); _attributeGenerator.AddIntroducedMemberAttribute(method, interfaceMethod, implementingMethod); _attributeGenerator.ReplicateAttributes(implementingMethod, method); return(method); }