/// <summary> /// Serialises an object to a speckle object. /// </summary> /// <param name="source">The object you want to serialise.</param> /// <param name="recursionDepth">Leave this blank, unless you really know what you're doing.</param> /// <param name="traversed">Leave this blank, unless you really know what you're doing.</param> /// <param name="path">Leave this blank, unless you really know what you're doing.</param> /// <param name="excludeAssebmlies">List of speckle kits assembly names to exclude from the search.</param> /// <returns></returns> public static SpeckleObject Serialise(object source, int recursionDepth = 0, Dictionary <int, string> traversed = null, string path = "", IEnumerable <string> excludeAssebmlies = null) { if (source == null) { return(new SpeckleNull()); } //if ( source is IEnumerable ) return Converter.Serialise( source as IEnumerable<object> ); if (traversed == null) { traversed = new Dictionary <int, string>(); } if (path == "") { path = "root"; } // check references if (traversed.ContainsKey(source.GetHashCode())) { return new SpeckleAbstract() { _type = "ref", _ref = traversed[source.GetHashCode()] } } ; else { traversed.Add(source.GetHashCode(), path); } // check if it already is a speckle object if (source is SpeckleObject) { return(source as SpeckleObject); } // check assemblies if (toSpeckleMethods.ContainsKey(source.GetType().ToString())) { return(toSpeckleMethods[source.GetType().ToString()].Invoke(source, new object[] { source }) as SpeckleObject); } var methods = new List <MethodInfo>(); foreach (var ass in SpeckleCore.SpeckleInitializer.GetAssemblies().Where(ass => (excludeAssebmlies != null ? !excludeAssebmlies.Contains(ass.FullName) : true))) { try { methods.AddRange(Converter.GetExtensionMethods(ass, source.GetType(), "ToSpeckle")); } catch { } // handling errors thrown when we're attempting to load something with missing references (ie, dynamo stuff in rhino, or vice-versa). } // if we have a "ToSpeckle" extension method, then invoke that and return its result if (methods.Count > 0) { try { var obj = methods[0].Invoke(source, new object[] { source }); if (obj != null) { toSpeckleMethods.Add(source.GetType().ToString(), methods[0]); return(obj as SpeckleObject); } else { return(new SpeckleNull()); } } catch { return(new SpeckleNull()); } } // else just continue with the to abstract part SpeckleAbstract result = new SpeckleAbstract(); result._type = source.GetType().Name; result._assembly = source.GetType().Assembly.FullName; Dictionary <string, object> dict = new Dictionary <string, object>(); var properties = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var prop in properties) { if (!prop.CanWrite) { continue; } try { var value = prop.GetValue(source); if (value == null) { continue; } dict[prop.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + prop.Name); } catch { } } var fields = source.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (var field in fields) { if (field.IsNotSerialized) { continue; } try { var value = field.GetValue(source); if (value == null) { continue; } dict[field.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + field.Name); } catch { } } result.Properties = dict; result.Hash = result.GeometryHash = result.GetMd5FromObject(result.Properties); return(result); }
/// <summary> /// Serialises an object to a speckle object. /// </summary> /// <param name="source">The object you want to serialise.</param> /// <param name="recursionDepth">Leave this blank, unless you really know what you're doing.</param> /// <param name="traversed">Leave this blank, unless you really know what you're doing.</param> /// <param name="path">Leave this blank, unless you really know what you're doing.</param> /// <returns></returns> public static SpeckleObject Serialise(object source, int recursionDepth = 0, Dictionary <int, string> traversed = null, string path = "") { // null check if (source == null) { return(new SpeckleNull()); } // init optional parameters if (traversed == null) { traversed = new Dictionary <int, string>(); } if (path == "") { path = "root"; } // check references if (traversed.ContainsKey(source.GetHashCode())) { return new SpeckleAbstract() { _type = "ref", _ref = traversed[source.GetHashCode()] } } ; else { traversed.Add(source.GetHashCode(), path); } // check if it already is a speckle object if (source is SpeckleObject) { return(source as SpeckleObject); } // check assemblies if (toSpeckleMethods.ContainsKey(source.GetType().ToString())) { return(toSpeckleMethods[source.GetType().ToString()].Invoke(source, new object[] { source }) as SpeckleObject); } List <Assembly> myAss = System.AppDomain.CurrentDomain.GetAssemblies().ToList().FindAll(s => s.FullName.Contains("Speckle") && s.FullName.Contains("Converter")); List <MethodInfo> methods = new List <MethodInfo>(); foreach (var ass in myAss) { methods.AddRange(Converter.GetExtensionMethods(ass, source.GetType(), "ToSpeckle")); } // if we have a "ToSpeckle" extension method, then invoke that and return its result if (methods.Count > 0) { try { var obj = methods[0].Invoke(source, new object[] { source }); return(obj as SpeckleObject); } catch { return(new SpeckleNull()); } } // else just continue with the to abstract part SpeckleAbstract result = new SpeckleAbstract(); result._type = source.GetType().Name; result._assembly = source.GetType().Assembly.FullName; Dictionary <string, object> dict = new Dictionary <string, object>(); var properties = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var prop in properties) { if (!prop.CanWrite) { continue; } try { var value = prop.GetValue(source); if (value == null) { continue; } dict[prop.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + prop.Name); } catch { } } var fields = source.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (var field in fields) { if (field.IsNotSerialized) { continue; } try { var value = field.GetValue(source); if (value == null) { continue; } dict[field.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + field.Name); } catch { } } result.Properties = dict; result.Hash = result.GeometryHash = result.GetMd5FromObject(result.Properties); return(result); }
/// <summary> /// Serialises an object to a speckle object. /// </summary> /// <param name="source">The object you want to serialise.</param> /// <param name="recursionDepth">Leave this blank, unless you really know what you're doing.</param> /// <param name="traversed">Leave this blank, unless you really know what you're doing.</param> /// <param name="path">Leave this blank, unless you really know what you're doing.</param> /// <param name="excludeAssebmlies">List of speckle kits assembly names to exclude from the search.</param> /// <returns></returns> public static object Serialise(object source, int recursionDepth = 0, Dictionary <int, string> traversed = null, string path = "", IEnumerable <string> excludeAssebmlies = null) { if (source == null) { return(new SpeckleNull()); } //if ( source is IEnumerable ) return Converter.Serialise( source as IEnumerable<object> ); if (traversed == null) { traversed = new Dictionary <int, string>(); } if (path == "") { path = "root"; } // check references if (traversed.ContainsKey(source.GetHashCode())) { return new SpeckleAbstract() { _type = "ref", _ref = traversed[source.GetHashCode()] } } ; else { traversed.Add(source.GetHashCode(), path); } // check if it already is a speckle object if (source is SpeckleObject) { return(source as SpeckleObject); } // check assemblies if (toSpeckleMethods.ContainsKey(source.GetType().ToString())) { return(toSpeckleMethods[source.GetType().ToString()].Invoke(source, new object[] { source })); } var methods = new List <MethodInfo>(); var currentType = source.GetType(); var baseTypes = new List <Type>(); // create a list of base types while (currentType != null) { baseTypes.Add(currentType); currentType = currentType.BaseType; } // populate the ToSpeckle method array foreach (var ass in SpeckleCore.SpeckleInitializer.GetAssemblies().Where(ass => (excludeAssebmlies != null ? !excludeAssebmlies.Contains(ass.FullName) : true))) { foreach (var type in baseTypes) { try { methods.AddRange(Converter.GetExtensionMethods(ass, type, "ToSpeckle")); } catch { } } } // iterate through the ToSpeckle method array if (methods.Count > 0) { foreach (var method in methods) { try { var obj = method.Invoke(source, new object[] { source }); if (obj != null) { toSpeckleMethods.Add(source.GetType().ToString(), method); return(obj); } } catch { return(new SpeckleNull()); } } } // if we haven't returned anything by this point, we should go abstract SpeckleAbstract result = new SpeckleAbstract(); result._type = source.GetType().Name; result._assembly = source.GetType().Assembly.FullName; Dictionary <string, object> dict = new Dictionary <string, object>(); var properties = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var prop in properties) { if (!prop.CanWrite) { continue; } try { var value = prop.GetValue(source); if (value == null) { continue; } dict[prop.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + prop.Name); } catch { } } var fields = source.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (var field in fields) { if (field.IsNotSerialized) { continue; } try { var value = field.GetValue(source); if (value == null) { continue; } dict[field.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + field.Name); } catch { } } result.Properties = dict; result.Hash = result.GeometryHash = result.GetMd5FromObject(result.GetMd5FromObject(result._assembly) + result.GetMd5FromObject(result._type) + result.GetMd5FromObject(result.Properties)); return(result); }