mirror of
https://github.com/cadmium-im/zirconium-sharp.git
synced 2024-11-22 10:22:23 +00:00
Implement plugin depending/exporting API feature in plugin system
This commit is contained in:
parent
fdf85d5055
commit
803d898f45
@ -3,6 +3,8 @@ namespace Zirconium.Core.Plugins.Interfaces
|
|||||||
public interface IPluginAPI
|
public interface IPluginAPI
|
||||||
{
|
{
|
||||||
void Initialize(IPluginHostAPI hostModuleAPI);
|
void Initialize(IPluginHostAPI hostModuleAPI);
|
||||||
|
void PreInitialize(IPluginManager pluginManager);
|
||||||
string GetPluginUniqueName();
|
string GetPluginUniqueName();
|
||||||
|
dynamic GetExportedAPI();
|
||||||
}
|
}
|
||||||
}
|
}
|
7
src/Zirconium/Core/Plugins/Interfaces/IPluginManager.cs
Normal file
7
src/Zirconium/Core/Plugins/Interfaces/IPluginManager.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Zirconium.Core.Plugins.Interfaces
|
||||||
|
{
|
||||||
|
public interface IPluginManager
|
||||||
|
{
|
||||||
|
dynamic Depends(IPluginAPI currentPlugin, string pluginName);
|
||||||
|
}
|
||||||
|
}
|
@ -6,20 +6,22 @@ using System.Threading;
|
|||||||
using McMaster.NETCore.Plugins;
|
using McMaster.NETCore.Plugins;
|
||||||
using Zirconium.Core.Models;
|
using Zirconium.Core.Models;
|
||||||
using Zirconium.Core.Plugins.Interfaces;
|
using Zirconium.Core.Plugins.Interfaces;
|
||||||
|
using Zirconium.Utils;
|
||||||
|
|
||||||
namespace Zirconium.Core.Plugins
|
namespace Zirconium.Core.Plugins
|
||||||
{
|
{
|
||||||
// Class which responsible for plugin managing (loading, initializing) and plugin lifetime cycle
|
// Class which responsible for plugin managing (loading, initializing) and plugin lifetime cycle
|
||||||
public class PluginManager
|
public class PluginManager : IPluginManager
|
||||||
{
|
{
|
||||||
private IList<IPluginAPI> _plugins;
|
private IDictionary<string, IPluginAPI> _plugins;
|
||||||
private IPluginHostAPI _pluginHostAPI;
|
private IPluginHostAPI _pluginHostAPI;
|
||||||
private Mutex _pluginsMutex;
|
private Mutex _pluginsMutex;
|
||||||
|
private string _currentPluginFolderPath;
|
||||||
|
|
||||||
public PluginManager(IPluginHostAPI hostModuleAPI)
|
public PluginManager(IPluginHostAPI hostModuleAPI)
|
||||||
{
|
{
|
||||||
_pluginHostAPI = hostModuleAPI;
|
_pluginHostAPI = hostModuleAPI;
|
||||||
_plugins = new List<IPluginAPI>();
|
_plugins = new Dictionary<string, IPluginAPI>();
|
||||||
_pluginsMutex = new Mutex();
|
_pluginsMutex = new Mutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,48 +34,71 @@ namespace Zirconium.Core.Plugins
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create module loaders
|
_currentPluginFolderPath = folderPath;
|
||||||
|
|
||||||
foreach (var dir in Directory.GetDirectories(folderPath))
|
foreach (var dir in Directory.GetDirectories(folderPath))
|
||||||
{
|
{
|
||||||
var dirName = Path.GetFileName(dir);
|
var pluginName = Path.GetFileName(dir);
|
||||||
if (enabledPlugins.Where(x => x == dirName).FirstOrDefault() == null) {
|
if (enabledPlugins.Where(x => x == pluginName).FirstOrDefault() == null)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var pluginDll = Path.Combine(dir, dirName + ".dll");
|
|
||||||
|
var plugin = this.LoadPlugin(pluginName);
|
||||||
|
_pluginsMutex.WaitOne();
|
||||||
|
_plugins[pluginName] = plugin;
|
||||||
|
_pluginsMutex.ReleaseMutex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPluginAPI LoadPlugin(string pluginName)
|
||||||
|
{
|
||||||
|
PluginLoader loader;
|
||||||
|
var pluginDll = Path.Combine(_currentPluginFolderPath, pluginName + ".dll");
|
||||||
if (File.Exists(pluginDll))
|
if (File.Exists(pluginDll))
|
||||||
{
|
{
|
||||||
Logging.Log.Debug("found plugin " + dirName);
|
Logging.Log.Debug("Found plugin " + pluginName);
|
||||||
Logging.Log.Debug("try to init plugin " + dirName);
|
Logging.Log.Debug("Try to initialize plugin " + pluginName);
|
||||||
var loader = PluginLoader.CreateFromAssemblyFile(
|
loader = PluginLoader.CreateFromAssemblyFile(
|
||||||
pluginDll,
|
pluginDll,
|
||||||
sharedTypes: new[] {
|
sharedTypes: new[] {
|
||||||
typeof(IPluginAPI),
|
typeof(IPluginAPI),
|
||||||
typeof(IPluginHostAPI),
|
typeof(IPluginHostAPI),
|
||||||
|
typeof(IPluginManager),
|
||||||
typeof(IC2SMessageHandler),
|
typeof(IC2SMessageHandler),
|
||||||
typeof(ICoreEventHandler),
|
typeof(ICoreEventHandler),
|
||||||
typeof(BaseMessage),
|
typeof(BaseMessage),
|
||||||
typeof(CoreEvent)
|
typeof(CoreEvent)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
loaders.Add(loader);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("specified plugin is not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an instance of module types
|
IPluginAPI plugin = null;
|
||||||
foreach (var loader in loaders)
|
|
||||||
{
|
|
||||||
foreach (var pluginType in loader
|
foreach (var pluginType in loader
|
||||||
.LoadDefaultAssembly()
|
.LoadDefaultAssembly()
|
||||||
.GetTypes()
|
.GetTypes()
|
||||||
.Where(t => typeof(IPluginAPI).IsAssignableFrom(t) && !t.IsAbstract))
|
.Where(t => typeof(IPluginAPI).IsAssignableFrom(t) && !t.IsAbstract))
|
||||||
{
|
{
|
||||||
// This assumes the implementation of IPlugin has a parameterless constructor
|
// This assumes the implementation of IPlugin has a parameterless constructor
|
||||||
IPluginAPI plugin = (IPluginAPI)Activator.CreateInstance(pluginType);
|
plugin = (IPluginAPI)Activator.CreateInstance(pluginType);
|
||||||
Logging.Log.Debug($"Created plugin instance '{plugin.GetPluginUniqueName()}'.");
|
Logging.Log.Debug($"Created plugin instance '{plugin.GetPluginUniqueName()}'.");
|
||||||
|
plugin.PreInitialize(this);
|
||||||
plugin.Initialize(_pluginHostAPI);
|
plugin.Initialize(_pluginHostAPI);
|
||||||
_plugins.Add(plugin);
|
|
||||||
}
|
}
|
||||||
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public dynamic Depends(IPluginAPI currentPlugin, string pluginName)
|
||||||
|
{
|
||||||
|
var dependantPlugin = _plugins.GetValueOrDefault(pluginName, null);
|
||||||
|
if (dependantPlugin != null) return dependantPlugin.GetExportedAPI();
|
||||||
|
this.LoadPlugin(pluginName);
|
||||||
|
dependantPlugin = _plugins[pluginName];
|
||||||
|
return dependantPlugin.GetExportedAPI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,13 +15,18 @@ namespace HelloWorldPlugin
|
|||||||
hostModuleAPI.Hook(handler);
|
hostModuleAPI.Hook(handler);
|
||||||
Log.Debug("plugin is initialized");
|
Log.Debug("plugin is initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PreInitialize(IPluginManager pluginManager) { }
|
||||||
|
|
||||||
|
public dynamic GetExportedAPI() { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class C2SHandler : IC2SMessageHandler
|
internal class C2SHandler : IC2SMessageHandler
|
||||||
{
|
{
|
||||||
private IPluginHostAPI hostModuleAPI;
|
private IPluginHostAPI hostModuleAPI;
|
||||||
|
|
||||||
public C2SHandler(IPluginHostAPI hostModuleAPI) {
|
public C2SHandler(IPluginHostAPI hostModuleAPI)
|
||||||
|
{
|
||||||
this.hostModuleAPI = hostModuleAPI;
|
this.hostModuleAPI = hostModuleAPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user