/// <summary> Determines an attribute string for the given instance reference. </summary> private string ReferenceToString(object tempValue, out bool reference) { reference = true; if (tempValue == null) { return(String.Empty); } else { Type type = tempValue.GetType(); PublishNameAttribute attribute = ((PublishNameAttribute)ReflectionUtility.GetAttribute(type, typeof(PublishNameAttribute))); if (attribute != null) { return((string)ReflectionUtility.GetMemberValue(ReflectionUtility.FindSimpleMember(type, attribute.MemberName), tempValue)); } else { var converter = Persistence.GetTypeConverter(type); if (converter != null) { reference = false; return(converter.ConvertToString(tempValue)); } } return(String.Empty); } }
/// <summary> Determines if the specified property should be serialized. </summary> private bool ShouldPersist(MemberInfo member, object tempValue, object instance) { DefaultValueAttribute defaultValues = (DefaultValueAttribute)ReflectionUtility.GetAttribute(member, typeof(DefaultValueAttribute)); if (defaultValues != null) { return(!Object.Equals(tempValue, defaultValues.Value)); } DefaultValueMemberAttribute defaultMember = (DefaultValueMemberAttribute)ReflectionUtility.GetAttribute(member, typeof(DefaultValueMemberAttribute)); if (defaultMember != null) { return (!Object.Equals ( tempValue, ReflectionUtility.GetMemberValue ( ReflectionUtility.FindSimpleMember(instance.GetType(), defaultMember.MemberName), instance ) )); } return(true); }
/// <summary> Finds the instance for a specific member. </summary> /// <remarks> /// Names with dot qualifiers are resolved to their unqualified names by finding /// a by-reference member for each qualifier for each instance. /// </remarks> /// <param name="LNamePath"> Pass the fully qualified name and get the simple name back. </param> /// <returns> The instance containing the member named the simple (unqualified) name. </returns> private static object FindMemberInstance(object LInstance, ref string LNamePath) { int dotPos; while ((dotPos = LNamePath.IndexOf('.')) >= 0) { LInstance = ReflectionUtility.GetMemberValue(ReflectionUtility.FindSimpleMember(LInstance.GetType(), LNamePath.Substring(0, dotPos)), LInstance); LNamePath = LNamePath.Substring(dotPos + 1); } ; return(LInstance); }
/// <summary> Gets the MemberInfo for the name member of the specified type. </summary> private MemberInfo GetNameMemberInfo(Type type) { PublishNameAttribute publishName = (PublishNameAttribute)ReflectionUtility.GetAttribute(type, typeof(PublishNameAttribute)); if (publishName == null) { return(null); } else { return(ReflectionUtility.FindSimpleMember(type, publishName.MemberName)); } }
/// <summary> Deserializes an instance from a node. </summary> /// <param name="node"> The XML node. This node will not be affected by this method. </param> /// <param name="instance"> An optional instance to deserialize "into". </param> /// <returns> The instance that was passed by AInstance or was constructed if null was passed. </returns> private object ReadObject(XElement node, object instance) { string elementName = node.Name.LocalName.Substring(node.Name.LocalName.LastIndexOf('.') + 1).ToLower(); // simple type name Type type; if (instance != null) // instance provided { type = instance.GetType(); string typeName = GetElementName(type); // result is lower case if (elementName != typeName) { Errors.Add(new BOPException(BOPException.Codes.TypeNameMismatch, elementName, typeName)); } } else // construct instance { type = GetClassType(elementName, node.Name.NamespaceName); try { if (!IsValueType(type)) { PublishDefaultConstructorAttribute constructorAttribute = (PublishDefaultConstructorAttribute)ReflectionUtility.GetAttribute(type, typeof(PublishDefaultConstructorAttribute)); if ((constructorAttribute == null) || (constructorAttribute.ConstructorSignature == String.Empty)) { instance = Activator.CreateInstance(type, new object[] { }); } else { // create a copy of the node to work with // so that the original is not corrupted by disappearing attributes node = new XElement(node); instance = ConstructInstance(constructorAttribute.ConstructorSignature, type, node); } } else { return(ReflectionUtility.StringToValue(node.Attribute("value").Value, type)); } } catch (Exception E) { throw new BOPException(BOPException.Codes.UnableToConstruct, E, type.FullName); } } MemberInfo member; object memberInstance; string memberName; Type memberType; // Have Type and Instance, now read the properties try { // Read attributes foreach (XAttribute attribute in node.Attributes()) { try { memberName = attribute.Name.LocalName.ToLower(); if ( (!attribute.IsNamespaceDeclaration) && !( IsBOPNode(attribute.Name) && (memberName.StartsWith(BOPType) || memberName.StartsWith(BOPDefault)) ) ) { if (IsBOPNode(attribute.Name)) { memberInstance = instance; if (Persistence.XNamesEqual(attribute.Name, XmlBOPName)) { member = GetNameMemberInfo(type); if (member == null) { throw new BOPException(BOPException.Codes.InvalidElementName, type.Name); } } else { throw new BOPException(BOPException.Codes.InvalidAttribute, attribute.Name); } } else { memberInstance = FindMemberInstance(instance, ref memberName); member = ReflectionUtility.FindSimpleMember(memberInstance.GetType(), memberName); } memberType = GetMemberType(node, member); ReflectionUtility.SetMemberValue ( member, memberInstance, ( AttributeToValue ( attribute.Value, memberType, memberInstance, member ) ) ); } } catch (Exception exception) { Errors.Add(exception); } } // Add this instance to the list of read instances if it has a name member = GetNameMemberInfo(instance.GetType()); if (member != null) { memberName = (string)ReflectionUtility.GetMemberValue(member, instance); if (memberName != String.Empty) { InstancesByName.Add(memberName, instance); } } // read child nodes IList list; foreach (XElement localNode in node.Elements()) { try { memberName = localNode.Name.LocalName.ToLower(); memberInstance = FindMemberInstance(instance, ref memberName); // First see if the member instance has a default list attribute and use it if it does string defaultListName = GetDefaultListMemberName(memberInstance.GetType()); if (defaultListName == String.Empty) { list = memberInstance as IList; } else // if no default list, assume the member instance IS the list { list = ReflectionUtility.GetMemberValue ( ReflectionUtility.FindSimpleMember(memberInstance.GetType(), defaultListName), memberInstance ) as IList; } if (list == null) { throw new BOPException(BOPException.Codes.DefaultListNotFound, memberInstance.GetType().Name); } list.Add(ReadObject(localNode, null)); } catch (Exception exception) { Errors.Add(exception); } } // call AfterDeserialize if (instance is IBOPSerializationEvents) { ((IBOPSerializationEvents)instance).AfterDeserialize(this); } if (AfterDeserialized != null) { AfterDeserialized(instance); } } catch { if ((instance != null) && (instance is IDisposable)) { ((IDisposable)instance).Dispose(); } throw; } return(instance); }
/// <summary> Constructs a new instance given a specified type and signature. </summary> /// <remarks> /// Any constructor arguments are loaded from the specified XML node. /// The specified node may be altered by this method. (clone it first if you do not want it affected) /// </remarks> private object ConstructInstance(string signature, Type type, XElement node) { // Determine the constructor signature string[] signatureNames = signature.Split(new char[] { ';' }); Type[] localSignature = new Type[signatureNames.Length]; for (int i = localSignature.Length - 1; i >= 0; i--) { localSignature[i] = ReflectionUtility.GetType(signatureNames[i], type.Assembly); } // Find the matching constructor ConstructorInfo constructor = type.GetConstructor(localSignature); if (constructor == null) { throw new BOPException(BOPException.Codes.DefaultConstructorNotFound, signature); } string nameMemberName = GetNameMemberName(type); // Build the constructor's parameter list ParameterInfo[] parameters = constructor.GetParameters(); object[] parameterValues = new object[parameters.Length]; PublishSourceAttribute source; for (int i = parameters.Length - 1; i >= 0; i--) // order doesn't matter so step down to avoid re-eval of length - 1 { source = (PublishSourceAttribute)ReflectionUtility.GetAttribute(parameters[i], typeof(PublishSourceAttribute)); if (source == null) { throw new BOPException(BOPException.Codes.ConstructorArgumentRefNotSpecified, parameters[i].Name, type.FullName); } var memberName = source.MemberName.ToLower(); XAttribute attribute = node.Attribute(memberName); if (attribute != null) { parameterValues[i] = AttributeToValue ( attribute.Value, GetMemberType(node, ReflectionUtility.FindSimpleMember(type, memberName)), null, null ); attribute.Remove(); // remove so we don't read the attribute later } else // didn't find a regular attribute, so look for a default tag in the xml { attribute = node.Attribute(XmlBOPDefault + source.MemberName.ToLower()); if (attribute != null) { parameterValues[i] = ReadAttributeDefault(ReflectionUtility.FindSimpleMember(type, memberName), null); attribute.Remove(); } else { // see if the property on the object has a DefaultValueAttribute set DefaultValueAttribute defaultValue = (DefaultValueAttribute)ReflectionUtility.GetAttribute(ReflectionUtility.FindSimpleMember(type, source.MemberName), typeof(DefaultValueAttribute)); if (defaultValue != null) { parameterValues[i] = defaultValue.Value; } else { throw new BOPException(BOPException.Codes.ConstructorArgumentRefNotFound, source.MemberName, type.FullName); } } } } return(constructor.Invoke(parameterValues)); }