private void Activate(PluginInstance instance) { Log.Debug(Tag, $"Attempting to load {instance.Name}"); if (IsAlreadyLoaded(instance.Assembly.GetName())) { return; } var types = instance.Assembly.GetExportedTypes(); // Only filter for types which can be instantiated and implement IPlugin somehow. var implementingType = types.FirstOrDefault( type => !type.IsInterface && !type.IsAbstract && type.GetInterface(nameof(IPlugin)) != null); if (implementingType == null) { throw new PluginLoadException("No exported types found implementing IPlugin.", instance.AssemblyDirectory); } // Activate base plugin var plugin = (IPlugin)Activator.CreateInstance(implementingType); if (plugin.ApiVersion != ApiVersion) { throw new PluginLoadException($"Plugin declares incompatible API version: expected {ApiVersion}, found {plugin.ApiVersion}.", instance.AssemblyDirectory); } instance.Info = plugin.Info; instance.Plugin = plugin; var servicePlugin = plugin as MusicService; var context = new PluginContext { PluginDirectory = instance.AssemblyDirectory }; instance.Context = context; if (servicePlugin != null) { var settingsPath = Program.DefaultApp.UserDataPathOf(Path.Combine(SettingsDir, String.Format(SettingsFileFormat, plugin.Info.Name))); var settingsFile = new SettingsFile(settingsPath, servicePlugin.Settings.GetType(), servicePlugin.Settings); instance.SettingsFile = settingsFile; } else { throw new PluginLoadException("IPlugin type does not implement MusicService.", instance.AssemblyDirectory); } }
public void LoadAll() { BeforeLoad(); // Plugins are stored in format {PluginDir}/{PluginName}/AthamePlugin.*.dll var subDirs = Directory.GetDirectories(PluginDirectory); isLoading = true; foreach (var dir in subDirs) { var name = Path.GetFileName(dir); try { // Attempt to load a .pdb if one exists var basePath = Path.Combine(dir, PluginDllPrefix + name); var dllFilename = basePath + ".dll"; var pdbFilename = basePath + ".pdb"; var theAssembly = File.Exists(pdbFilename) ? Assembly.Load(File.ReadAllBytes(dllFilename), File.ReadAllBytes(pdbFilename)) : Assembly.Load(File.ReadAllBytes(dllFilename)); // Set basic information about the assembly var plugin = new PluginInstance { Assembly = theAssembly, AssemblyDirectory = dir, Name = name }; Plugins.Add(plugin); Activate(plugin); AreAnyLoaded = true; } catch (Exception ex) { Log.WriteException(Level.Error, Tag, ex, $"While loading plugin {name}"); var eventArgs = new PluginLoadExceptionEventArgs { PluginName = name, Exception = ex, Continue = true }; LoadException?.Invoke(this, eventArgs); if (!eventArgs.Continue) { return; } } } isLoading = false; }