/// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }