private Assembly LoadAssemblyFromPathInternal(string assemblyFullPath) { if (assemblyFullPath == null) throw new ArgumentNullException("assemblyFullPath"); assemblyFullPath = Path.GetFullPath(assemblyFullPath); try { lock (loadedAssemblies) { LoadedAssembly loadedAssembly; if (loadedAssembliesByName.TryGetValue(assemblyFullPath, out loadedAssembly)) { return loadedAssembly.Assembly; } if (!File.Exists(assemblyFullPath)) return null; // Find pdb (if it exists) var pdbFullPath = Path.ChangeExtension(assemblyFullPath, ".pdb"); if (!File.Exists(pdbFullPath)) pdbFullPath = null; // PreLoad the assembly into memory without locking it var assemblyBytes = File.ReadAllBytes(assemblyFullPath); var pdbBytes = pdbFullPath != null ? File.ReadAllBytes(pdbFullPath) : null; // Load the assembly into the current AppDomain // TODO: Is using AppDomain would provide more opportunities for unloading? var assembly = pdbBytes != null ? Assembly.Load(assemblyBytes, pdbBytes) : Assembly.Load(assemblyBytes); loadedAssembly = new LoadedAssembly(assemblyFullPath, assembly); loadedAssemblies.Add(loadedAssembly); loadedAssembliesByName.Add(assemblyFullPath, loadedAssembly); // Force assembly resolve with proper name // (doing it here, because if done later, loadingInstance will be set to null and it won't work) Assembly.Load(assembly.FullName); // Make sure that all referenced assemblies are loaded here foreach (var assemblyRef in assembly.GetReferencedAssemblies()) { Assembly.Load(assemblyRef); } // Make sure that Module initializer are called if (assembly.GetTypes().Length > 0) { foreach (var module in assembly.Modules) { RuntimeHelpers.RunModuleConstructor(module.ModuleHandle); } } return assembly; } } catch (Exception exception) { log.Error("Error while loading assembly reference [{0}]", exception, assemblyFullPath); var loaderException = exception as ReflectionTypeLoadException; if (loaderException != null) { foreach (var exceptionForType in loaderException.LoaderExceptions) { log.Error("Unable to load type. See exception.", exceptionForType); } } } return null; }
private Assembly LoadAssemblyFromPathInternal(string assemblyFullPath) { if (assemblyFullPath == null) { throw new ArgumentNullException("assemblyFullPath"); } assemblyFullPath = Path.GetFullPath(assemblyFullPath); try { lock (loadedAssemblies) { LoadedAssembly loadedAssembly; if (loadedAssembliesByName.TryGetValue(assemblyFullPath, out loadedAssembly)) { return(loadedAssembly.Assembly); } if (!File.Exists(assemblyFullPath)) { return(null); } // Find pdb (if it exists) var pdbFullPath = Path.ChangeExtension(assemblyFullPath, ".pdb"); if (!File.Exists(pdbFullPath)) { pdbFullPath = null; } // PreLoad the assembly into memory without locking it var assemblyBytes = File.ReadAllBytes(assemblyFullPath); var pdbBytes = pdbFullPath != null?File.ReadAllBytes(pdbFullPath) : null; // Load the assembly into the current AppDomain Assembly assembly; if (new UDirectory(AppDomain.CurrentDomain.BaseDirectory) == new UFile(assemblyFullPath).GetFullDirectory()) { // If loading from base directory, don't even try to load through byte array, as Assembly.Load will notice there is a "safer" version to load // This happens usually when opening Xenko assemblies themselves assembly = Assembly.LoadFrom(assemblyFullPath); } else { // TODO: Is using AppDomain would provide more opportunities for unloading? assembly = pdbBytes != null?Assembly.Load(assemblyBytes, pdbBytes) : Assembly.Load(assemblyBytes); loadedAssembly = new LoadedAssembly(assemblyFullPath, assembly); loadedAssemblies.Add(loadedAssembly); loadedAssembliesByName.Add(assemblyFullPath, loadedAssembly); // Force assembly resolve with proper name // (doing it here, because if done later, loadingInstance will be set to null and it won't work) Assembly.Load(assembly.FullName); } // Make sure that all referenced assemblies are loaded here foreach (var assemblyRef in assembly.GetReferencedAssemblies()) { Assembly.Load(assemblyRef); } // Make sure that Module initializer are called if (assembly.GetTypes().Length > 0) { foreach (var module in assembly.Modules) { RuntimeHelpers.RunModuleConstructor(module.ModuleHandle); } } return(assembly); } } catch (Exception exception) { log.Error($"Error while loading assembly reference [{assemblyFullPath}]", exception); var loaderException = exception as ReflectionTypeLoadException; if (loaderException != null) { foreach (var exceptionForType in loaderException.LoaderExceptions) { log.Error("Unable to load type. See exception.", exceptionForType); } } } return(null); }