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)))); } }
// 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)); } }
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))); } }
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)); } }
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)); }
private void ExplicitlyImplementOnDeserialization(MutableType proxyType, MethodInfo initializationMethod) { proxyType.AddInterface(typeof(IDeserializationCallback)); proxyType.AddExplicitOverride(s_onDeserializationMethod, ctx => CallInitializationMethod(ctx.This, initializationMethod)); }