Skip to content

Commit

Permalink
feat(plugins): Improve plugin loading process
Browse files Browse the repository at this point in the history
- Refactored the `LoadPluginManifests` method in the `PluginsLoader` class to accept a collection of plugin types as an optional parameter.
- Added a new method `GetPluginManifestTypes` that retrieves all exported types from loaded assemblies that implement the `IPlugin` interface and returns them as a dictionary with their corresponding assembly.
- Updated the `LoadPluginManifests` method to use the provided plugin types or retrieve them using the new method if not provided.
- Removed unnecessary clearing of `PluginManifestsInternal`.
- Improved error logging by catching exceptions during instantiation of plugins and logging specific error messages.
  • Loading branch information
SakuraIsayeki committed Jul 16, 2023
1 parent ac6376f commit 844863c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 23 deletions.
8 changes: 5 additions & 3 deletions src/YumeChan.Core/CommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ public async Task UninstallCommandsAsync()

public async Task RegisterCommandsAsync()
{
_logger.LogInformation("Using PluginBase v{Version}.", typeof(IPlugin).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion);
_logger.LogInformation("Current Plugins directory: {PluginsDirectory}", _pluginsLoader.PluginsLoadDirectory);
_logger.LogInformation("Using PluginBase v{version}.", typeof(IPlugin).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion);
_logger.LogInformation("Current Plugins directory: {pluginsDirectory}", _pluginsLoader.PluginsLoadDirectory);

await _pluginsFetcher.FetchPluginsAsync();
_pluginsLoader.ScanDirectoryForPluginFiles();
Expand All @@ -124,7 +124,9 @@ public async Task RegisterCommandsAsync()
_container.Populate(handler.ConfigureServices(new ServiceCollection()));
}

_pluginsLoader.LoadPluginManifests();
Dictionary<Assembly, Type> pluginManifestTypes = _pluginsLoader.GetPluginManifestTypes();
_container.RegisterMany(pluginManifestTypes.Values, serviceTypeCondition: type => type.IsAssignableTo(typeof(IPlugin)));
_pluginsLoader.LoadPluginManifests(pluginManifestTypes);

// Add YumeCore internal commands
_pluginsLoader.ImportPlugin(new Modules.InternalPlugin());
Expand Down
38 changes: 18 additions & 20 deletions src/YumeChan.Core/Services/Plugins/PluginsLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,35 +127,33 @@ internal void ImportPlugin(IPlugin plugin, Assembly? assembly = null)
// Also try add the assembly to the list of plugin assemblies.
_pluginAssemblies.TryAdd(plugin.AssemblyName, assembly ?? plugin.GetType().Assembly);
}

internal IEnumerable<IPlugin> LoadPluginManifests()

internal Dictionary<Assembly, Type> GetPluginManifestTypes() => new(
from a in _loadAssemblies
from t in a.ExportedTypes
where t.ImplementsInterface(typeof(IPlugin))
select new KeyValuePair<Assembly, Type>(a, t)
);

internal IEnumerable<IPlugin> LoadPluginManifests(IEnumerable<KeyValuePair<Assembly, Type>>? pluginTypes = null)
{
PluginManifestsInternal.Clear();

pluginTypes ??= GetPluginManifestTypes();

foreach (Assembly a in _loadAssemblies)
foreach (var (a, t) in pluginTypes)
{
try
{
// Try to load the plugin manifests from the assemblies, log error in console if unsuccessful.
foreach (Type t in a.ExportedTypes.Where(static x => x.ImplementsInterface(typeof(IPlugin))))
{
try
{
// Moment of truth...
IPlugin plugin = InstantiateManifest(t)!;

// It works! Import it.
ImportPlugin(plugin, a);
}
catch (Exception e)
{
YumeCore.Instance.Logger.LogError(e,"Failed to instantiate plugin {pluginName}.", t.Name);
}
}
// Moment of truth...
IPlugin plugin = InstantiateManifest(t)!;

// It works! Import it.
ImportPlugin(plugin, a);
}
catch (Exception e)
{
YumeCore.Instance.Logger.LogError(e,"Failed to load plugin manifests from assembly {assemblyFullName}.", a.FullName);
YumeCore.Instance.Logger.LogError(e,"Failed to instantiate plugin {pluginName}.", t.Name);
}
}

Expand Down

0 comments on commit 844863c

Please sign in to comment.