public override object ExtractObject(Type requestedType) { object buildObject; if (IsReferedMultipleTimes) { if (ParentGraph.TryGetObjectForRefId(RefId, out buildObject)) { return(buildObject); } } Type typeToBuild = requestedType; if (ObjectType != null) { Type myType = ObjectType.ClassType; if (requestedType != null && !requestedType.IsAssignableFrom(myType)) { throw new Exception("Unable to build object. Requested on type but data has another type"); //TODO better exception } typeToBuild = myType; } if (typeToBuild == null) { throw new Exception("Missing type information. Unable to build object"); //TODO better exception } if (typeToBuild.IsAbstract || typeToBuild.IsInterface) { throw new Exception("Cannot create a direct instance of a abstract or interface"); //TODO better exception } if (typeToBuild.IsArray || typeToBuild.IsPrimitiveData()) { //Handle Boxed Value Types IGraphNode boxedValue = m_fields[DEFAULT_BOXED_VALUE_FIELD_NAME]; return(boxedValue.RebuildObject(typeToBuild)); } buildObject = SerializationServices.GetUninitializedObject(typeToBuild); ParentGraph.LinkObjectToNode(this, buildObject); var surrogate = SerializationServices.GetDefaultSerializationSurrogate(typeToBuild); surrogate.SetObjectData(ref buildObject, this); return(buildObject); }
public IGraphNode BuildNode(object obj, Type fieldType) { if (obj == null) { return(null); } IGraphNode result; Type objType = obj.GetType(); if (typeof(Type).IsAssignableFrom(objType)) { return(GetTypeEntry((Type)obj)); } var formatter = GetFormatter(objType); if (formatter != null) { var node = formatter.ObjectToGraphNode(obj, this); var fieldTypeFormatter = fieldType != null?GetFormatter(fieldType) : null; if (formatter != fieldTypeFormatter) { //Value needs to be boxed ObjectGraphNode box = node as ObjectGraphNode; if (box == null) { box = (ObjectGraphNode)CreateObjectData(); box[DEFAULT_BOXED_VALUE_FIELD_NAME] = node; } if (box.ObjectType == null) { box.ObjectType = GetTypeEntry(objType); } return(box); } return(node); } if (objType.IsArray || objType.IsPrimitiveData()) { //Boxable Values (arrays, bools, numbers, strings) IGraphNode valueNode; if (objType.IsArray) { Type elemType = objType.GetElementType(); ISequenceGraphNode array = BuildSequenceNode(); IEnumerator it = ((IEnumerable)obj).GetEnumerator(); while (it.MoveNext()) { IGraphNode elem = BuildNode(it.Current, elemType); array.Add(elem); } valueNode = array; } else { //Primitive data type if (objType == typeof(string)) { valueNode = BuildStringNode(obj as string); } else { if (objType.IsEnum) { obj = Convert.ChangeType(obj, ((Enum)obj).GetTypeCode()); } valueNode = BuildPrimitiveNode(obj as ValueType); } } if (objType != fieldType) { //Value needs to be boxed var boxNode = CreateObjectData(); boxNode.ObjectType = GetTypeEntry(objType); boxNode[DEFAULT_BOXED_VALUE_FIELD_NAME] = valueNode; valueNode = boxNode; } result = valueNode; } else { //Non-Boxable Values (structs and objects) IObjectGraphNode objReturnData; bool extractData = true; if (objType.IsValueType) { //Structure objReturnData = CreateObjectData(); } else { //Classes if (!GetObjectNode(obj, out objReturnData)) { extractData = false; } } if (extractData) { var surrogate = SerializationServices.GetDefaultSerializationSurrogate(objType); surrogate.GetObjectData(obj, objReturnData); } if ((objReturnData.ObjectType == null) && (objType != fieldType)) { objReturnData.ObjectType = GetTypeEntry(objType); } result = objReturnData; } return(result); }