protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed && disposing)
            {
                this.disposing = true;

                GC.Collect();
                GC.WaitForPendingFinalizers();

                if (this.assemblyReferences != null)
                {
                    foreach (var reference in this.assemblyReferences)
                    {
                        // https://docs.microsoft.com/en-us/dotnet/standard/assembly/unloadability#use-collectible-assemblyloadcontext
                        for (int i = 0; reference.IsAlive && (i < 10); i++)
                        {
                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                        }
                    }
                }


                // Unload any loaded native assemblies
                foreach (var nativeAssembly in this.loadedNativeLibraries)
                {
                    this.nativeAssemblyUnloader.UnloadNativeAssembly(nativeAssembly.Key, nativeAssembly.Value);
                }

                this.loadedPlugins.Clear();
                this.assemblyReferences.Clear();
                this.loadedNativeLibraries.Clear();
                this.pluginDependencyContext?.Dispose();
                this.pluginDependencyResolver?.Dispose();
                this.resolver?.Dispose();
                this.resolver = null;
                this.loadedNativeLibraries             = null;
                this.loadedPlugins                     = null;
                this.assemblyReferences                = null;
                this.assemblyLoadStrategy              = null;
                this.pluginDependencyContext           = null;
                this.pluginDependencyResolver          = null;
                this.fullPathToPluginAssembly          = null;
                this.initialPluginLoadDirectory        = null;
                this.pluginPlatformVersion             = null;
                this.nativeAssemblyUnloader            = null;
                this.pluginDependencyResolverFactory   = null;
                this.assemblyLoadStrategyFactory       = null;
                this.assemblyDependencyResolverFactory = null;
                this.fileSystemUtilities               = null;
                this.runtimeDefaultAssemblyLoadContext = null;
                this.pluginDependencyContextProvider   = null;
            }
            this.disposed = true;
        }
 public DefaultAssemblyLoadContext(Func <INativeAssemblyUnloader> nativeAssemblyUnloaderFactory,
                                   Func <IPluginDependencyResolver> pluginDependencyResolverFactory,
                                   Func <IAssemblyLoadStrategy> assemblyLoadStrategyFactory,
                                   Func <string, IAssemblyDependencyResolver> assemblyDependencyResolverFactory,
                                   Func <IFileSystemUtilities> fileSystemUtilitiesFactory,
                                   Func <IRuntimeDefaultAssemblyContext> runtimeDefaultAssemblyLoadContextFactory,
                                   Func <IPluginDependencyContextProvider> pluginDependencyContextProviderFactory)
 {
     this.nativeAssemblyUnloader            = nativeAssemblyUnloaderFactory.ThrowIfNull(nameof(nativeAssemblyUnloaderFactory))();
     this.pluginDependencyResolverFactory   = pluginDependencyResolverFactory.ThrowIfNull(nameof(pluginDependencyResolverFactory));
     this.assemblyLoadStrategyFactory       = assemblyLoadStrategyFactory.ThrowIfNull(nameof(assemblyLoadStrategyFactory));
     this.assemblyDependencyResolverFactory = assemblyDependencyResolverFactory.ThrowIfNull(nameof(assemblyDependencyResolverFactory));
     this.fileSystemUtilities = fileSystemUtilitiesFactory.ThrowIfNull(nameof(fileSystemUtilitiesFactory))();
     this.runtimeDefaultAssemblyLoadContext = runtimeDefaultAssemblyLoadContextFactory.ThrowIfNull(nameof(runtimeDefaultAssemblyLoadContextFactory))();
     this.pluginDependencyContextProvider   = pluginDependencyContextProviderFactory.ThrowIfNull(nameof(pluginDependencyContextProviderFactory))();
     this.loadedNativeLibraries             = new ConcurrentDictionary <string, IntPtr>();
     this.loadedPlugins      = new ConcurrentBag <string>();
     this.assemblyReferences = new ConcurrentBag <WeakReference>();
 }