diff --git a/Source/Editor/Plugins/PluginUtils.cs b/Source/Editor/Plugins/PluginUtils.cs index 1ba8767c6..755c57d7e 100644 --- a/Source/Editor/Plugins/PluginUtils.cs +++ b/Source/Editor/Plugins/PluginUtils.cs @@ -84,7 +84,7 @@ namespace FlaxEditor editorPlugin = null; // Cache data - var allAssemblies = AppDomain.CurrentDomain.GetAssemblies(); + var allAssemblies = Utils.GetAssemblies(); var gameAssembly = Utils.GetAssemblyByName("Game", allAssemblies); var gameEditorAssembly = Utils.GetAssemblyByName("Game.Editor", allAssemblies); var gameAssemblyTypes = gameAssembly.GetTypes(); diff --git a/Source/Editor/Scripting/TypeUtils.cs b/Source/Editor/Scripting/TypeUtils.cs index c2e839b3d..949d2a0a2 100644 --- a/Source/Editor/Scripting/TypeUtils.cs +++ b/Source/Editor/Scripting/TypeUtils.cs @@ -191,7 +191,7 @@ namespace FlaxEditor.Scripting /// Additional callback used to check if the given type is valid. Returns true if add type, otherwise false. public static void GetDerivedTypes(ScriptType baseType, List result, Func checkFunc) { - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + var assemblies = Utils.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { GetDerivedTypes(assemblies[i], baseType, result, checkFunc); @@ -208,7 +208,7 @@ namespace FlaxEditor.Scripting public static void GetDerivedTypes(ScriptType baseType, List result, Func checkFunc, Func checkAssembly) { // C#/C++ types - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + var assemblies = Utils.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { if (checkAssembly(assemblies[i])) @@ -246,7 +246,7 @@ namespace FlaxEditor.Scripting public static void GetTypes(List result, Func checkFunc, Func checkAssembly) { // C#/C++ types - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + var assemblies = Utils.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { if (checkAssembly(assemblies[i])) @@ -285,7 +285,7 @@ namespace FlaxEditor.Scripting /// Additional callback used to check if the given assembly is valid. Returns true if search for types in the given assembly, otherwise false. public static void GetTypesWithAttributeDefined(Type attributeType, List result, Func checkFunc, Func checkAssembly) { - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + var assemblies = Utils.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { if (checkAssembly(assemblies[i])) @@ -302,7 +302,7 @@ namespace FlaxEditor.Scripting { if (string.IsNullOrEmpty(typeName)) return null; - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + var assemblies = Utils.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { var assembly = assemblies[i]; @@ -332,7 +332,7 @@ namespace FlaxEditor.Scripting if (type != null) return new ScriptType(type); } - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + var assemblies = Utils.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { var assembly = assemblies[i]; diff --git a/Source/Engine/Content/JsonAsset.cs b/Source/Engine/Content/JsonAsset.cs index 5a7339e43..2d83920c8 100644 --- a/Source/Engine/Content/JsonAsset.cs +++ b/Source/Engine/Content/JsonAsset.cs @@ -35,11 +35,8 @@ namespace FlaxEngine return null; var dataTypeName = DataTypeName; - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); - - // Going through the assemblies in order will return collected assemblies first, - // use reverse order instead to find the type currently loaded assemblies instead. - for (int i = assemblies.Length-1; i >= 0; i--) + var assemblies = Utils.GetAssemblies(); + for (int i = 0; i < assemblies.Length; i++) { var assembly = assemblies[i]; if (assembly != null) diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index 967503c51..9ee57e3cd 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -1038,7 +1038,7 @@ namespace FlaxEngine private static Dictionary loadedNativeLibraries = new(); private static Dictionary nativeLibraryPaths = new(); private static Dictionary assemblyOwnedNativeLibraries = new(); - private static AssemblyLoadContext scriptingAssemblyLoadContext; + internal static AssemblyLoadContext scriptingAssemblyLoadContext; [System.Diagnostics.DebuggerStepThrough] private static IntPtr NativeLibraryImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? dllImportSearchPath) @@ -2453,7 +2453,7 @@ namespace FlaxEngine // This assembly was already loaded when initializing the host context firstAssemblyLoaded = true; - Assembly flaxEngineAssembly = AppDomain.CurrentDomain.GetAssemblies().First(x => x.GetName().Name == "FlaxEngine.CSharp"); + Assembly flaxEngineAssembly = AssemblyLoadContext.Default.Assemblies.First(x => x.GetName().Name == "FlaxEngine.CSharp"); *assemblyName = NativeAllocStringAnsi(flaxEngineAssembly.GetName().Name); *assemblyFullName = NativeAllocStringAnsi(flaxEngineAssembly.FullName); return GetAssemblyHandle(flaxEngineAssembly); @@ -2476,7 +2476,7 @@ namespace FlaxEngine // This assembly was already loaded when initializing the host context firstAssemblyLoaded = true; - Assembly flaxEngineAssembly = AppDomain.CurrentDomain.GetAssemblies().First(x => x.GetName().Name == "FlaxEngine.CSharp"); + Assembly flaxEngineAssembly = AssemblyLoadContext.Default.Assemblies.First(x => x.GetName().Name == "FlaxEngine.CSharp"); *assemblyName = NativeAllocStringAnsi(flaxEngineAssembly.GetName().Name); *assemblyFullName = NativeAllocStringAnsi(flaxEngineAssembly.FullName); return GetAssemblyHandle(flaxEngineAssembly); @@ -2517,13 +2517,9 @@ namespace FlaxEngine internal static ManagedHandle GetAssemblyByName(IntPtr name_, IntPtr* assemblyName, IntPtr* assemblyFullName) { string name = Marshal.PtrToStringAnsi(name_); - Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.GetName().Name == name); + Assembly assembly = Utils.GetAssemblies().FirstOrDefault(x => x.GetName().Name == name); if (assembly == null) - { - assembly = scriptingAssemblyLoadContext.Assemblies.FirstOrDefault(x => x.GetName().Name == name); - if (assembly == null) - return new ManagedHandle(); - } + return new ManagedHandle(); *assemblyName = NativeAllocStringAnsi(assembly.GetName().Name); *assemblyFullName = NativeAllocStringAnsi(assembly.FullName); @@ -2593,14 +2589,9 @@ namespace FlaxEngine internal static ManagedHandle GetAssemblyObject(IntPtr assemblyName_) { string assemblyName = Marshal.PtrToStringAnsi(assemblyName_); - Assembly assembly = null; - assembly = scriptingAssemblyLoadContext.Assemblies.FirstOrDefault(x => x.FullName == assemblyName); + Assembly assembly = Utils.GetAssemblies().FirstOrDefault(x => x.FullName == assemblyName); if (assembly == null) - { - assembly = System.AppDomain.CurrentDomain.GetAssemblies().First(x => x.FullName == assemblyName); - if (assembly == null) - return new ManagedHandle(); - } + return new ManagedHandle(); return ManagedHandle.Alloc(assembly); } @@ -2864,7 +2855,7 @@ namespace FlaxEngine // We need private types of this assembly too, DefinedTypes contains a lot of types from other assemblies... var types = referencedTypes.Any() ? assembly.DefinedTypes.Where(x => !referencedTypes.Contains(x.FullName)).ToArray() : assembly.DefinedTypes.ToArray(); - Assert.IsTrue(AppDomain.CurrentDomain.GetAssemblies().Where(x => x.GetName().Name == "FlaxEngine.CSharp").Count() == 1); + Assert.IsTrue(Utils.GetAssemblies().Where(x => x.GetName().Name == "FlaxEngine.CSharp").Count() == 1); return types; } diff --git a/Source/Engine/Utilities/Utils.cs b/Source/Engine/Utilities/Utils.cs index c7f2dc70a..e4dae22be 100644 --- a/Source/Engine/Utilities/Utils.cs +++ b/Source/Engine/Utilities/Utils.cs @@ -5,9 +5,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Runtime.InteropServices.Marshalling; +using System.Runtime.Loader; namespace FlaxEngine { @@ -184,6 +183,19 @@ namespace FlaxEngine return true; } + /// + /// Gets all currently loaded assemblies in the runtime. + /// + /// List of assemblies + public static Assembly[] GetAssemblies() + { +#if USE_NETCORE + return AssemblyLoadContext.Default.Assemblies.Concat(NativeInterop.scriptingAssemblyLoadContext.Assemblies).ToArray(); +#else + return AppDomain.CurrentDomain.GetAssemblies(); +#endif + } + /// /// Gets the assembly with the given name. /// @@ -191,7 +203,7 @@ namespace FlaxEngine /// The assembly or null if not found. public static Assembly GetAssemblyByName(string name) { - return GetAssemblyByName(name, AppDomain.CurrentDomain.GetAssemblies()); + return GetAssemblyByName(name, GetAssemblies()); } /// diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index 8accd14dd..341fd6746 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -1229,7 +1229,7 @@ namespace Flax.Build.Bindings // Abstract wrapper (to ensure C# class can be created for Visual Scripts, see NativeInterop.NewObject) if (classInfo.IsAbstract) - contents.AppendLine().Append(indent).Append("[Unmanaged] private sealed class AbstractWrapper : ").Append(classInfo.Name).AppendLine(" { }"); + contents.AppendLine().Append(indent).Append("[Unmanaged] [HideInEditor] private sealed class AbstractWrapper : ").Append(classInfo.Name).AppendLine(" { }"); // Nested types foreach (var apiTypeInfo in classInfo.Children)