public static IEnumerable <string> FindPluginAssemblies(string pluginFolder, bool includeFramework = false) { // Storage to ensure not loading the same assembly twice and optimize calls to GetAssemblies() IDictionary <string, bool> loaded = new ConcurrentDictionary <string, bool>(); CacheAlreadyLoadedAssemblies(loaded, includeFramework); if (!IsPluginFolderNameSupplied()) { yield break; } pluginFolder = Path.GetFullPath(pluginFolder); if (!Directory.Exists(pluginFolder)) { _logger.Debug($"Plugin folder '{pluginFolder}' does not exist. No plugins will be loaded."); yield break; } var assemblies = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories); var pluginAssemblyLoadContext = new PluginAssemblyLoadContext(); try { foreach (var assemblyPath in assemblies) { var assembly = pluginAssemblyLoadContext.LoadFromAssemblyPath(assemblyPath); if (!HasPlugin(assembly)) { continue; } string assemblyDirectory = Path.GetDirectoryName(assemblyPath); var assemblyMetadata = ReadAssemblyMetadata(assembly); if (IsExtensionAssembly(assemblyMetadata)) { var validator = GetExtensionValidator(); var validationResult = validator.ValidateObject(assemblyDirectory); if (!validationResult.Any()) { yield return(assembly.Location); } else { _logger.Warn($"Assembly: {assembly.GetName()} - {string.Join(",", validationResult)}"); } } else if (IsProfileAssembly(assemblyMetadata)) { yield return(assembly.Location); } } } finally { pluginAssemblyLoadContext.Unload(); }