/// <summary> /// Tries read an entry of the data by the path and creates a new class/struct. /// </summary> /// <param name="type"> The type. </param> /// <param name="className"> Name of the class. </param> /// <param name="values"> Values of the class. </param> /// <param name="path"> The path. </param> /// <param name="storer"> The storer. </param> /// <param name="entries"> List of the entries of the storer. </param> /// <param name="references"> Dictionary that contains references to the objects. </param> /// <returns> Graph if graph has been created successfully, otherwise null. </returns> private object TryReadFormattable(string path, Type type, string className, IDictionary <string, string> values, IReadOnlyDataStorer storer, LinkedList <IDataStorerEntry> entries, Dictionary <string, object> references) { // Tries get the formattable type that is related (same) with the declared type FormattableType formattableType = this.formattableTypes.FindOrDefault(f => f.Name == className && f.IsRelatedType(type, false)); if (formattableType == null) { // Tries get the formattable type that is related (not same, derived) with the declared type formattableType = this.formattableTypes.FindOrDefault(f => f.IsRelatedType(type, true)); } if (formattableType == null) { // Formattable type is null -> type isn't supported -> returns null return(null); } object graph = formattableType.CreateInstance(type); references.Add(path, graph); formattableType.OnDeserializing(graph); // Restores the keys and values of the objects FormattableValue[] formattableValues = formattableType.GetValues(type); int length = formattableValues.Length; FormattableValue value = null; Type valueType = null; string valueName = ""; for (int i = 0; i < length; i++) { value = formattableValues[i]; valueType = value.Type; valueName = value.Name; if (this.IsPrimitive(valueType)) { // Value of the object is primitive - reads it from information file Func <string, object> primitiveConverter = this.GetPrimitiveConverterToObject(valueType); if (values.ContainsKey(value.Name)) { value.SetValue(graph, primitiveConverter(values[valueName])); } else { if (!value.Optional) { throw new KeyCanNotLoadedException(formattableType, valueName); } } } else { // Value of the object isn't primitive - reads it from special file try { value.SetValue(graph, this.Read( value.Type, StringUtils.Combine(path, valueName, DirectorySeparatorString), storer, entries, references )); } catch (Exception ex) { // Thrown error if value isn't optional if (!value.Optional) { throw new KeyCanNotLoadedException(formattableType, valueName, ex); } } } } formattableType.OnDeserialized(graph); // Makes the substitution (if required) object substitution = formattableType.Substitution(graph); if (substitution != graph) { references.Remove(path); references.Add(path, substitution); // Returns the substituted graph return(substitution); } else { // Returns the created graph return(graph); } }