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))));
            }
        }
Exemplo n.º 3
0
        public void AddInterfaces(IEnumerable <Type> interfacesToImplement)
        {
            ArgumentUtility.CheckNotNull("interfacesToImplement", interfacesToImplement);

            foreach (var ifc in interfacesToImplement)
            {
                _concreteTarget.AddInterface(ifc);
            }
        }
        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)));
            }
        }
Exemplo n.º 5
0
        public MutableMethodInfo GetOrCreateImplementation(MutableType declaringType, MethodInfo interfaceMethod, out bool isNewlyCreated)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNull("interfaceMethod", interfaceMethod);
            Assertion.IsNotNull(interfaceMethod.DeclaringType);

            if (!interfaceMethod.DeclaringType.IsInterface)
            {
                throw new ArgumentException("The specified method is not an interface method.", "interfaceMethod");
            }

            CheckIsNotMethodInstantiation(interfaceMethod, "interfaceMethod");

            // ReSharper disable PossibleUnintendedReferenceComparison
            if (!interfaceMethod.DeclaringType.IsTypePipeAssignableFrom(declaringType))
            // ReSharper restore PossibleUnintendedReferenceComparison
            {
                Assertion.IsNotNull(interfaceMethod.DeclaringType);
                var message = string.Format(
                    "Method is declared by an interface that is not implemented by the proxy: '{0}'.", interfaceMethod.DeclaringType.Name);
                throw new ArgumentException(message, "interfaceMethod");
            }

            var baseImplementation = GetOrCreateImplementationMethod(declaringType, interfaceMethod, out isNewlyCreated);

            if (baseImplementation is MutableMethodInfo)
            {
                return((MutableMethodInfo)baseImplementation);
            }

            Assertion.IsTrue(baseImplementation.IsVirtual, "It is not possible to get an interface implementation that is not virtual (in verifiable code).");

            // Re-implement if final.
            if (baseImplementation.IsFinal)
            {
                if (!SubclassFilterUtility.IsVisibleFromSubclass(baseImplementation))
                {
                    Assertion.IsNotNull(baseImplementation.DeclaringType);
                    var message = string.Format(
                        "Cannot re-implement interface method '{0}' because its base implementation on '{1}' is not accessible.",
                        interfaceMethod.Name,
                        baseImplementation.DeclaringType.Name);
                    throw new NotSupportedException(message);
                }

                declaringType.AddInterface(interfaceMethod.DeclaringType, throwIfAlreadyImplemented: false);

                var attributes = interfaceMethod.Attributes.Unset(MethodAttributes.Abstract);
                Func <MethodBodyCreationContext, Expression> bodyProvider = ctx => ctx.DelegateToBase(baseImplementation);

                isNewlyCreated = true;
                return(CreateMethod(declaringType, interfaceMethod, interfaceMethod.Name, attributes, bodyProvider));
            }

            return(GetOrCreateOverride(declaringType, baseImplementation, out isNewlyCreated));
        }
        private void AddRequiredInterfaces(MutableType nextCallProxy, TargetClassDefinition targetClassDefinition)
        {
            var interfaces = EnumerableUtility
                             .Singleton(typeof(IGeneratedNextCallProxyType))
                             .Concat(targetClassDefinition.RequiredNextCallTypes.Select(requiredType => requiredType.Type));

            foreach (var ifc in interfaces)
            {
                nextCallProxy.AddInterface(ifc);
            }
        }
Exemplo n.º 7
0
        public void DefineTypeFacets()
        {
            var typeInitializer = _mutableType.AddTypeInitializer(ctx => Expression.Empty());

            var instanceInitialization = ExpressionTreeObjectMother.GetSomeExpression();

            _mutableType.AddInitialization(ctx => instanceInitialization);

            var customAttribute = CustomAttributeDeclarationObjectMother.Create();

            _mutableType.AddCustomAttribute(customAttribute);

            var @interface = typeof(IDisposable);

            _mutableType.AddInterface(@interface);

            var field       = _mutableType.AddField();
            var constructor = _mutableType.AddConstructor();
            var method      = _mutableType.AddMethod();
            var property    = _mutableType.AddProperty();
            var event_      = _mutableType.AddEvent();

            using (_mockRepository.Ordered())
            {
                var context = PopulateContext(_generator, 2);

                _typeBuilderMock.Expect(mock => mock.SetParent(_mutableType.BaseType));

                _memberEmitterMock.Expect(mock => mock.AddConstructor(context, typeInitializer));

                _initializationBuilderMock.Expect(mock => mock.CreateInitializationMembers(_mutableType)).Return(_fakeInitializationMembers);
                _proxySerializationEnablerMock.Expect(mock => mock.MakeSerializable(_mutableType, _fakeInitializationMethod));

                _typeBuilderMock.Expect(mock => mock.SetCustomAttribute(customAttribute));
                _typeBuilderMock.Expect(mock => mock.AddInterfaceImplementation(@interface));
                _memberEmitterMock.Expect(mock => mock.AddField(context, field));
                _initializationBuilderMock.Expect(
                    mock => mock.WireConstructorWithInitialization(constructor, _fakeInitializationMembers, _proxySerializationEnablerMock));
                _memberEmitterMock.Expect(mock => mock.AddConstructor(context, constructor));
                _memberEmitterMock.Expect(mock => mock.AddMethod(context, method));
                SetupExpectationsForAccessors(_memberEmitterMock, _mutableType.AddedMethods.Except(new[] { method }));
                _memberEmitterMock.Expect(mock => mock.AddProperty(context, property));
                _memberEmitterMock.Expect(mock => mock.AddEvent(context, event_));
            }
            _mockRepository.ReplayAll();

            _generator.DefineTypeFacets();

            _mockRepository.VerifyAll();
        }
Exemplo n.º 8
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));
        }
Exemplo n.º 9
0
        public static void AddInterface(this MutableType mutableType, Type interfaceType = null)
        {
            interfaceType = interfaceType ?? ReflectionObjectMother.GetSomeInterfaceType();

            mutableType.AddInterface(interfaceType);
        }
Exemplo n.º 10
0
 private void ExplicitlyImplementOnDeserialization(MutableType proxyType, MethodInfo initializationMethod)
 {
     proxyType.AddInterface(typeof(IDeserializationCallback));
     proxyType.AddExplicitOverride(s_onDeserializationMethod, ctx => CallInitializationMethod(ctx.This, initializationMethod));
 }
 public void AddInterfaces()
 {
     _type.AddInterface(typeof(ISerializable));
     _type.AddInterface(typeof(IGeneratedMixinType));
 }