public MixinSerializationHelper(SerializationInfo info, StreamingContext context) { ArgumentUtility.CheckNotNull("info", info); _context = context; var identifierDeserializer = new SerializationInfoConcreteMixinTypeIdentifierDeserializer(info, "__identifier"); var identifier = ConcreteMixinTypeIdentifier.Deserialize(identifierDeserializer); var pipelineIdentifier = info.GetString("__participantConfigurationID"); var pipeline = SafeServiceLocator.Current.GetInstance <IPipelineRegistry>().Get(pipelineIdentifier); var mixinType = pipeline.ReflectionService.GetAdditionalType(identifier); _baseMemberValues = (object[])info.GetValue("__baseMemberValues", typeof(object[])); // Usually, instantiate a deserialized object using GetSafeUninitializedObject. // However, _baseMemberValues being null means that the object itself manages its member deserialization via ISerializable. In such a case, we // need to use the deserialization constructor to instantiate the object. if (_baseMemberValues != null) { _deserializedObject = FormatterServices.GetSafeUninitializedObject(mixinType); } else { Assertion.IsTrue(typeof(ISerializable).IsAssignableFrom(mixinType)); _deserializedObject = Activator.CreateInstance( mixinType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { info, context }, null); } SerializationImplementer.RaiseOnDeserializing(_deserializedObject, _context); }
// Here, we can rely on everything being deserialized as needed. public void OnDeserialization(object sender) { if (_baseMemberValues != null) { var baseType = _deserializedObject.GetType().BaseType; Assertion.IsNotNull(baseType, "Mixed types always have a base type."); MemberInfo[] baseMembers = FormatterServices.GetSerializableMembers(baseType); FormatterServices.PopulateObjectMembers(_deserializedObject, baseMembers, _baseMemberValues); } SerializationImplementer.RaiseOnDeserialized(_deserializedObject, _context); SerializationImplementer.RaiseOnDeserialization(_deserializedObject, sender); // Note: This and Next properties are initialized from the target class via InitializeDeserializedMixinTarget }
public void ImplementGetObjectData() { // TODO 5811: This does exactly the same as what ComplexSerializationEnabler does, but with a different ID (ConcreteMixinTypeIdentifier instead // of AssembledTypeID) and a different way to get the type back from the pipeline (GetAdditionalType instead of GetAssembledType). // Consider refactoring ComplexSerializationEnabler to allow this code to be replaced. SerializationImplementer.ImplementGetObjectDataByDelegation( _type, (ctx, baseIsISerializable) => Expression.Call( null, s_getObjectDataForGeneratedTypesMethod, ctx.Parameters[0], ctx.Parameters[1], ctx.This, _identifierField, Expression.Constant(!baseIsISerializable), Expression.Constant(_pipelineIdentifier))); }