Seperated out assembly resolution logic to it's own function

This commit is contained in:
SS
2023-11-07 16:30:50 -07:00
parent 77b6a4a68b
commit 52a1175f96

View File

@@ -19,14 +19,15 @@ namespace FlaxEngine.Json.JsonCustomSerializers
{ {
private record struct TypeKey(string? assemblyName, string typeName); private record struct TypeKey(string? assemblyName, string typeName);
private ConcurrentDictionary<TypeKey, Type> _cache; private ConcurrentDictionary<TypeKey, Type> _typeCache;
private Func<TypeKey, Type> _resolve; private Func<TypeKey, Type> _resolveType;
/// <summary>Clear the cache</summary> /// <summary>Clear the cache</summary>
/// <remarks>Should be cleared on scripting domain reload to avoid out of date types participating in dynamic type resolution</remarks> /// <remarks>Should be cleared on scripting domain reload to avoid out of date types participating in dynamic type resolution</remarks>
public void ResetCache() public void ResetCache()
{ {
_cache.Clear(); _typeCache.Clear();
} }
public override Type BindToType(string? assemblyName, string typeName) public override Type BindToType(string? assemblyName, string typeName)
@@ -43,11 +44,11 @@ namespace FlaxEngine.Json.JsonCustomSerializers
public ExtendedSerializationBinder() public ExtendedSerializationBinder()
{ {
_resolve = ResolveBind; _resolveType = ResolveType;
_cache = new(); _typeCache = new();
} }
Type ResolveBind(TypeKey key) Type ResolveType(TypeKey key)
{ {
Type? type = null; Type? type = null;
if (key.assemblyName is null) { // No assembly name, attempt to find globally if (key.assemblyName is null) { // No assembly name, attempt to find globally
@@ -55,18 +56,7 @@ namespace FlaxEngine.Json.JsonCustomSerializers
} }
if (type is null && key.assemblyName is not null) { // Type not found yet, but we have assembly name if (type is null && key.assemblyName is not null) { // Type not found yet, but we have assembly name
Assembly? assembly = null; var assembly = ResolveAssembly(new(key.assemblyName));
assembly = FindScriptingAssembly(new(key.assemblyName)); // Attempt to find in scripting assemblies
if (assembly is null)
assembly = FindLoadAssembly(new(key.assemblyName)); // Attempt to load
if (assembly is null)
assembly = FindDomainAssembly(new(key.assemblyName)); // Attempt to find in the current domain
if (assembly is null)
throw MakeAsmResolutionException(key.assemblyName); // Assembly failed to resolve
type = FindTypeInAssembly(key.typeName, assembly); // We have assembly, attempt to load from assembly type = FindTypeInAssembly(key.typeName, assembly); // We have assembly, attempt to load from assembly
} }
@@ -80,6 +70,25 @@ namespace FlaxEngine.Json.JsonCustomSerializers
return type; return type;
} }
Assembly ResolveAssembly(AssemblyName name)
{
Assembly? assembly = null;
assembly = FindScriptingAssembly(name); // Attempt to find in scripting assemblies
if (assembly is null)
assembly = FindLoadAssembly(name); // Attempt to load
if (assembly is null)
assembly = FindDomainAssembly(name); // Attempt to find in the current domain
if (assembly is null)
throw MakeAsmResolutionException(name.FullName); // Assembly failed to resolve
return assembly;
}
/// <summary>Attempt to find the assembly among loaded scripting assemblies</summary> /// <summary>Attempt to find the assembly among loaded scripting assemblies</summary>
Assembly? FindScriptingAssembly(AssemblyName assemblyName) Assembly? FindScriptingAssembly(AssemblyName assemblyName)
{ {
@@ -91,7 +100,7 @@ namespace FlaxEngine.Json.JsonCustomSerializers
{ {
var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToArray(); var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToArray();
foreach (Assembly assembly in assemblies) { foreach (Assembly assembly in assemblies) { // Looking in domain may be necessary (in case of anon dynamic assembly for example)
var curName = assembly.GetName(); var curName = assembly.GetName();
if (curName == assemblyName || curName.Name == assemblyName.Name) if (curName == assemblyName || curName.Name == assemblyName.Name)
@@ -115,7 +124,7 @@ namespace FlaxEngine.Json.JsonCustomSerializers
} }
/// <summary>Attempt to find a type in a specified assembly</summary>
Type? FindTypeInAssembly(string typeName, Assembly assembly) Type? FindTypeInAssembly(string typeName, Assembly assembly)
{ {
var type = assembly.GetType(typeName); // Attempt to load directly var type = assembly.GetType(typeName); // Attempt to load directly
@@ -135,10 +144,9 @@ namespace FlaxEngine.Json.JsonCustomSerializers
/// <summary>Get type from the cache</summary> /// <summary>Get type from the cache</summary>
private Type FindCachedType(TypeKey key) private Type FindCachedType(TypeKey key)
{ {
return _cache.GetOrAdd(key, _resolve); return _typeCache.GetOrAdd(key, _resolveType);
} }
/********************************************* /*********************************************
** Below code is adapted from Newtonsoft.Json ** Below code is adapted from Newtonsoft.Json