Tolerate unloadable types in ServerShared reflection scans
CultCache discovers DatabaseEntry types by scanning every loaded assembly. Outside Unity, plugin assemblies that reference UnityEngine throw ReflectionTypeLoadException and took the whole scan down; keep the types that do load. Also fix GetAllGenericChildClasses reading and writing the ChildClasses cache instead of its own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
007350b327
commit
97a9e7a598
1 changed files with 16 additions and 8 deletions
|
|
@ -8,13 +8,23 @@ using System.Threading.Tasks;
|
|||
|
||||
public static class ReflectionExtensions
|
||||
{
|
||||
// Every type that can be loaded from every assembly in the domain. An assembly whose dependencies are missing
|
||||
// (a Unity plugin referencing UnityEngine when running outside Unity) still yields the types that do load.
|
||||
private static IEnumerable<Type> LoadableTypes()
|
||||
{
|
||||
return AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly =>
|
||||
{
|
||||
try { return assembly.GetTypes(); }
|
||||
catch (ReflectionTypeLoadException e) { return e.Types.Where(t => t != null); }
|
||||
});
|
||||
}
|
||||
|
||||
private static Dictionary<Type,Type[]> InterfaceClasses = new Dictionary<Type, Type[]>();
|
||||
public static Type[] GetAllInterfaceClasses(this Type type)
|
||||
{
|
||||
if (InterfaceClasses.ContainsKey(type))
|
||||
return InterfaceClasses[type];
|
||||
return InterfaceClasses[type] = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(ass => ass.GetTypes()).Where(t => t.IsClass && t.GetInterfaces().Contains(type)).ToArray();
|
||||
return InterfaceClasses[type] = LoadableTypes().Where(t => t.IsClass && t.GetInterfaces().Contains(type)).ToArray();
|
||||
}
|
||||
|
||||
private static Dictionary<Type,Type[]> ParentTypes = new Dictionary<Type, Type[]>();
|
||||
|
|
@ -56,17 +66,15 @@ public static class ReflectionExtensions
|
|||
{
|
||||
if (ChildClasses.ContainsKey(type))
|
||||
return ChildClasses[type];
|
||||
return ChildClasses[type] = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(ass => ass.GetTypes()).Where(type.IsAssignableFrom).ToArray();
|
||||
return ChildClasses[type] = LoadableTypes().Where(type.IsAssignableFrom).ToArray();
|
||||
}
|
||||
|
||||
|
||||
private static Dictionary<Type,Type[]> GenericChildClasses = new Dictionary<Type, Type[]>();
|
||||
public static Type[] GetAllGenericChildClasses(this Type genericType)
|
||||
{
|
||||
if (GenericChildClasses.ContainsKey(genericType))
|
||||
return ChildClasses[genericType];
|
||||
return ChildClasses[genericType] = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(ass => ass.GetTypes()).Where(type=>type.IsAssignableToGenericType(genericType)).ToArray();
|
||||
return GenericChildClasses[genericType];
|
||||
return GenericChildClasses[genericType] = LoadableTypes().Where(type=>type.IsAssignableToGenericType(genericType)).ToArray();
|
||||
}
|
||||
|
||||
public static bool IsAssignableToGenericType(this Type givenType, Type genericType)
|
||||
|
|
|
|||
Loading…
Reference in a new issue