Parcourir la source

Improving speed of RegisterClasses

Kenric Nugteren il y a 1 an
Parent
commit
f0e06c511c
2 fichiers modifiés avec 59 ajouts et 82 suppressions
  1. 57 80
      InABox.Core/CoreUtils.cs
  2. 2 2
      InABox.Core/Licensing/LicenseUtils.cs

+ 57 - 80
InABox.Core/CoreUtils.cs

@@ -99,7 +99,7 @@ namespace InABox.Core
 
 
         
-        private static readonly List<Type> entities = new List<Type>();
+        private static readonly Dictionary<string, Type> entities = new Dictionary<string, Type>();
 
         public static Dictionary<string, long> TypeListSummary = new Dictionary<string, long>();
 
@@ -110,7 +110,10 @@ namespace InABox.Core
         private static readonly Regex StripSpecialCharacters = new Regex(@"&#(.|\n)*?;|&nbsp;|&gt;|&lt;&quot;", RegexOptions.Compiled);
         private static readonly Regex StripLineBreaks = new Regex(@"( |\r?\n|\r|\n)\1+", RegexOptions.Compiled);
         
-        public static IEnumerable<Type> Entities => entities;
+        /// <summary>
+        /// Return all <see cref="Type"/> that have been loaded through use of the <see cref="RegisterClasses(Assembly[])"/> function.
+        /// </summary>
+        public static IEnumerable<Type> Entities => entities.Values;
 
         public static long GenerateSequence()
         {
@@ -212,7 +215,7 @@ namespace InABox.Core
                     && !myType.IsAbstract
                     && !myType.IsGenericType
                     && myType.IsSubclassOf(typeof(Entity))
-            ).ToArray();
+            );
 
             foreach (var entity in entities)
             {
@@ -294,7 +297,7 @@ namespace InABox.Core
 
         public static void RegisterClasses()
         {
-            RegisterClasses(typeof(CoreUtils).GetTypeInfo().Assembly);
+            RegisterClasses(typeof(CoreUtils).Assembly);
             ImportFactory.Register(typeof(CSVImporter<>), "Comma Separated", "Comma Separated Files (*.csv)|*.csv");
             ImportFactory.Register(typeof(TabImporter<>), "Tab Delimited", "Tab-Delimited Files (*.txt)|*.txt");
             ImportFactory.Register(typeof(FixedWidthImporter<>), "Fixed Width", "Text Files (*.txt)|*.txt");
@@ -302,18 +305,9 @@ namespace InABox.Core
 
         public static void RegisterClasses(params Assembly[] assemblies)
         {
-            foreach (var assembly in assemblies)
+            foreach(var type in assemblies.SelectMany(x => IterateTypes(x)).Where(x => !x.IsAbstract))
             {
-                var types = TypeList(
-                    new[] { assembly },
-                    myType =>
-                        //myType.GetTypeInfo().IsClass && 
-                        !myType.GetTypeInfo().IsAbstract
-                        //&& !myType.GetTypeInfo().IsGenericType
-                        //&& myType.GetTypeInfo().IsSubclassOf(typeof(Entity))
-                        && !entities.Contains(myType)
-                );
-                entities.AddRange(types);
+                entities.TryAdd(type.EntityName(), type);
             }
         }
 
@@ -341,10 +335,7 @@ namespace InABox.Core
 
         private static Type? FindType(string name)
         {
-            var result = entities.FirstOrDefault(x => x.EntityName().Equals(name));
-            if (result is null)
-                result = Type.GetType(name);
-            return result;
+            return entities.GetValueOrDefault(name) ?? Type.GetType(name);
         }
 
         public static bool TryGetEntity(string? entityname, [NotNullWhen(true)] out Type? type)
@@ -406,24 +397,16 @@ namespace InABox.Core
             var result = new List<Type>();
             try
             {
-                try
-                {
-                    foreach (var type in entities.Where(x => x != null).Cast<TypeInfo>())
-                        try
-                        {
-                            if (Predicate(type.AsType()) && !result.Contains(type.AsType()))
-                                result.Add(type.AsType());
-                        }
-                        catch (Exception e)
-                        {
-                            //Console.WriteLine(type.Name + " : " + tl.Message);
-                            Logger.Send(LogType.Error, "", $"Error in CoreUtils.TypeList: {CoreUtils.FormatException(e)}");
-                        }
-                }
-                catch (Exception e)
-                {
-                    Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
-                }
+                foreach (var type in entities.Values.Where(x => x != null))
+                    try
+                    {
+                        if (Predicate(type))
+                            result.Add(type);
+                    }
+                    catch (Exception e)
+                    {
+                        LogException("", e, "Error in CoreUtils.TypeList");
+                    }
             }
             catch (Exception e)
             {
@@ -439,60 +422,54 @@ namespace InABox.Core
         /// <param name="assemblies"></param>
         /// <param name="Predicate"></param>
         /// <returns></returns>
-        public static IList<Type> TypeList(IEnumerable<Assembly> assemblies, Func<Type, bool> Predicate)
+        public static IEnumerable<Type> IterateTypes(Assembly assembly)
         {
-            var result = new List<Type>();
+            Type[] types;
             try
+            {
+                types = assembly.GetTypes();
+            }
+            catch (ReflectionTypeLoadException e0)
+            {
+                types = e0.Types;
+            }
+            catch (Exception)
+            {
+                types = Array.Empty<Type>();
+            }
+
+            foreach (var type in types)
+            {
+                if (type != null)
+                {
+                    yield return type;
+                }
+            }
+        }
+
+        /// <summary>
+        ///     Returns a list of types present within the assemblies.
+        /// </summary>
+        /// <param name="assemblies"></param>
+        /// <param name="Predicate"></param>
+        /// <returns></returns>
+        public static ICollection<Type> TypeList(IEnumerable<Assembly> assemblies, Func<Type, bool> Predicate)
+        {
+            var result = new HashSet<Type>();
+            foreach (var assembly in assemblies)
             {
                 try
                 {
-                    foreach (var assembly in assemblies) //.Where(x=>!x.IsDynamic))
-                        try
-                        {
-                            Type[] types;
-                            try
-                            {
-                                types = assembly.GetTypes();
-                            }
-                            catch (ReflectionTypeLoadException e0)
-                            {
-                                types = e0.Types;
-                            }
-                            catch (Exception)
-                            {
-                                types = Array.Empty<Type>();
-                            }
-
-                            foreach (var type in types.Where(x => x != null).Cast<TypeInfo>())
-                                try
-                                {
-                                    var asType = type.AsType();
-                                    if (Predicate(asType))
-                                    {
-                                        if (!result.Any(x => String.Equals(x.EntityName(), asType.EntityName())))
-                                            result.Add(asType);
-                                    }
-                                }
-                                catch (Exception el)
-                                {
-                                    Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", el.Message, el.StackTrace));
-                                    //Console.WriteLine(type.Name + " : " + tl.Message);
-                                }
-                        }
-                        catch (Exception e)
-                        {
-                            Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
-                        }
+                    foreach(var type in IterateTypes(assembly).Where(Predicate))
+                    {
+                        result.Add(type);
+                    }
                 }
                 catch (Exception e)
                 {
                     Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
                 }
             }
-            catch (Exception e)
-            {
-                Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
-            }
 
             return result;
         }

+ 2 - 2
InABox.Core/Licensing/LicenseUtils.cs

@@ -247,7 +247,7 @@ namespace InABox.Core
                     && !myType.IsAbstract
                     && !myType.IsGenericType
                     && myType.IsSubclassOf(typeof(LicenseToken))
-            ).ToArray();
+            );
 
             var entities = CoreUtils.TypeList(
                 AppDomain.CurrentDomain.GetAssemblies(),
@@ -256,7 +256,7 @@ namespace InABox.Core
                     && !myType.IsAbstract
                     && !myType.IsGenericType
                     && myType.IsSubclassOf(typeof(Entity))
-            ).ToArray();
+            );
 
             foreach (var entity in entities)
             {