コード例 #1
0
        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))));
            }
        }
コード例 #2
0
        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))));
            }
        }
コード例 #3
0
        // Required base call method implemented by "this" -> either overridden or not
        // If overridden, delegate to next in chain, else simply delegate to "this" field
        private void ImplementBaseCallForRequirementOnTarget(RequiredMethodDefinition requiredMethod)
        {
            var methodImplementation = _type.AddExplicitOverride(requiredMethod.InterfaceMethod, ctx => Expression.Default(ctx.ReturnType));

            if (requiredMethod.ImplementingMethod.Overrides.Count == 0) // this is not an overridden method, call method directly on _this
            {
                methodImplementation.SetBody(ctx => _nextCallMethodGenerator.CreateBaseCallToTarget(ctx, requiredMethod.ImplementingMethod));
            }
            else // this is an override, go to next in chain
            {
                // a base call for this might already have been implemented as an overriden method, but we explicitly implement the call chains anyway: it's
                // slightly easier and better for performance
                Assertion.IsFalse(_targetClassDefinition.Methods.ContainsKey(requiredMethod.InterfaceMethod));
                methodImplementation.SetBody(ctx => _nextCallMethodGenerator.CreateBaseCallToNextInChain(ctx, requiredMethod.ImplementingMethod));
            }
        }
コード例 #4
0
        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)));
            }
        }
コード例 #5
0
        public void ImplementOverridingMethods(TargetClassDefinition targetClassDefinition, IList <IMixinInfo> mixinInfos)
        {
            ArgumentUtility.CheckNotNull("mixinInfos", mixinInfos);

            var overriders = targetClassDefinition.GetAllMethods().Where(methodDefinition => methodDefinition.Base != null);

            foreach (var overrider in overriders)
            {
                var mixin = overrider.Base.DeclaringClass as MixinDefinition;
                Assertion.IsNotNull(mixin, "We only support mixins as overriders of target class members.");
                var mixinInfo = mixinInfos[mixin.MixinIndex];
                var methodInOverrideInterface = mixinInfo.GetOverrideInterfaceMethod(overrider.Base.MethodInfo);

                // It's necessary to explicitly implement some members defined by the concrete mixins' override interfaces: implicit implementation doesn't
                // work if the overrider is non-public or generic. Because it's simpler, we just implement all the members explicitly.
                var methodToCall = overrider.MethodInfo;
                _concreteTarget.AddExplicitOverride(methodInOverrideInterface, ctx => (Expression)ctx.DelegateTo(ctx.This, methodToCall));
            }
        }
コード例 #6
0
        public Tuple <FieldInfo, MethodInfo> CreateInitializationMembers(MutableType mutableType)
        {
            ArgumentUtility.CheckNotNull("mutableType", mutableType);

            var initialization = mutableType.Initialization;

            if (initialization.Expressions.Count == 0)
            {
                return(null);
            }

            mutableType.AddInterface(typeof(IInitializableObject));

            var counter           = mutableType.AddField("<tp>_ctorRunCounter", FieldAttributes.Private, typeof(int));
            var nonSerializedCtor = MemberInfoFromExpressionUtility.GetConstructor(() => new NonSerializedAttribute());

            counter.AddCustomAttribute(new CustomAttributeDeclaration(nonSerializedCtor, new object[0]));

            var initializationMethod = mutableType.AddExplicitOverride(s_interfaceMethod, ctx => CreateInitializationBody(ctx, initialization));

            return(Tuple.Create <FieldInfo, MethodInfo> (counter, initializationMethod));
        }
コード例 #7
0
 private void ExplicitlyImplementOnDeserialization(MutableType proxyType, MethodInfo initializationMethod)
 {
     proxyType.AddInterface(typeof(IDeserializationCallback));
     proxyType.AddExplicitOverride(s_onDeserializationMethod, ctx => CallInitializationMethod(ctx.This, initializationMethod));
 }