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)));
            }
        }
Exemple #4
0
        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);
        }