diff --git a/src/Zirconium/Core/Plugins/IPC/ExportedIPCMethod.cs b/src/Zirconium/Core/Plugins/IPC/ExportedIPCMethod.cs new file mode 100644 index 0000000..bc291fd --- /dev/null +++ b/src/Zirconium/Core/Plugins/IPC/ExportedIPCMethod.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Reflection; +namespace Zirconium.Core.Plugins.IPC +{ + public class ExportedIPCMethod + { + public object Service { get; set; } + public string MethodName { get; set; } + public MethodInfo Method { get; set; } + } +} \ No newline at end of file diff --git a/src/Zirconium/Core/Plugins/IPC/ExportedIPCMethodAttribute.cs b/src/Zirconium/Core/Plugins/IPC/ExportedIPCMethodAttribute.cs new file mode 100644 index 0000000..e0f53cc --- /dev/null +++ b/src/Zirconium/Core/Plugins/IPC/ExportedIPCMethodAttribute.cs @@ -0,0 +1,13 @@ +namespace Zirconium.Core.Plugins.IPC +{ + [System.AttributeUsage(System.AttributeTargets.Method)] + public class ExportedIPCMethodAttribute : System.Attribute + { + public string MethodName { get; private set; } + + public ExportedIPCMethodAttribute(string name) + { + this.MethodName = name; + } + } +} \ No newline at end of file diff --git a/src/Zirconium/Core/Plugins/IPC/IPCRouter.cs b/src/Zirconium/Core/Plugins/IPC/IPCRouter.cs new file mode 100644 index 0000000..42c5b13 --- /dev/null +++ b/src/Zirconium/Core/Plugins/IPC/IPCRouter.cs @@ -0,0 +1,53 @@ +using System.Threading.Tasks; +using System.Linq; +using System; +using System.Collections.Generic; +using Zirconium.Utils; + +namespace Zirconium.Core.Plugins.IPC +{ + public class IPCRouter + { + private IDictionary> methodTable = new Dictionary>(); + + public void RegisterIPCService(string pluginName, object service) + { + Type t = service.GetType(); + var exportedMethods = t.GetMethods() + .Where(m => m.GetCustomAttributes(typeof(ExportedIPCMethodAttribute), false).Length > 0) + .ToArray(); + foreach (var m in exportedMethods) + { + var attr = (ExportedIPCMethodAttribute)m.GetCustomAttributes(typeof(ExportedIPCMethodAttribute), false).First(); + var exportedMethod = new ExportedIPCMethod(); + exportedMethod.Service = service; + exportedMethod.MethodName = attr.MethodName; + exportedMethod.Method = m; + if (methodTable.GetValueOrDefault(pluginName, null) == null) + { + methodTable[pluginName] = new List(); + } + methodTable[pluginName].Add(exportedMethod); + } + } + + public Task MakeRequest(string pluginName, string methodName, dynamic paramsObject) + { + return Task.Factory.StartNew(() => + { + var method = methodTable[pluginName].Where(x => x.MethodName == methodName).FirstOrDefault(); + var returnValue = method.Method.Invoke(method.Service, new object[] {paramsObject}); + return returnValue; + }); + } + + public Task MakeNotif(string pluginName, string methodName, dynamic paramsObject) + { + return Task.Factory.StartNew(() => + { + var method = methodTable[pluginName].Where(x => x.MethodName == methodName).FirstOrDefault(); + method.Method.Invoke(method.Service, paramsObject); + }); + } + } +} \ No newline at end of file diff --git a/src/Zirconium/Core/Plugins/Interfaces/IPluginAPI.cs b/src/Zirconium/Core/Plugins/Interfaces/IPluginAPI.cs index d772d76..729535c 100644 --- a/src/Zirconium/Core/Plugins/Interfaces/IPluginAPI.cs +++ b/src/Zirconium/Core/Plugins/Interfaces/IPluginAPI.cs @@ -7,7 +7,5 @@ namespace Zirconium.Core.Plugins.Interfaces void Initialize(IPluginHostAPI hostModuleAPI); void PreInitialize(IPluginManager pluginManager); string GetPluginUniqueName(); - dynamic GetExportedAPI(); - Type[] GetExportedTypes(); } } \ No newline at end of file diff --git a/src/Zirconium/Core/Plugins/Interfaces/IPluginHostAPI.cs b/src/Zirconium/Core/Plugins/Interfaces/IPluginHostAPI.cs index 6a4b763..f5fd1dc 100644 --- a/src/Zirconium/Core/Plugins/Interfaces/IPluginHostAPI.cs +++ b/src/Zirconium/Core/Plugins/Interfaces/IPluginHostAPI.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Zirconium.Core.Models; namespace Zirconium.Core.Plugins.Interfaces @@ -17,5 +18,8 @@ namespace Zirconium.Core.Plugins.Interfaces dynamic GetSettings(string pluginName); void ProvideAuth(IAuthProvider provider); IExposedSessionManager GetSessionManager(); + void RegisterIPCService(IPluginAPI plugin, dynamic service); + Task MakeIPCRequest(string pluginName, string methodName, dynamic paramsObject); + Task MakeIPCNotification(string pluginName, string methodName, dynamic paramsObject); } } \ No newline at end of file diff --git a/src/Zirconium/Core/Plugins/Interfaces/IPluginManager.cs b/src/Zirconium/Core/Plugins/Interfaces/IPluginManager.cs index 7196d6c..c506e47 100644 --- a/src/Zirconium/Core/Plugins/Interfaces/IPluginManager.cs +++ b/src/Zirconium/Core/Plugins/Interfaces/IPluginManager.cs @@ -2,6 +2,6 @@ namespace Zirconium.Core.Plugins.Interfaces { public interface IPluginManager { - dynamic Depends(IPluginAPI currentPlugin, string pluginName); + void Depends(IPluginAPI currentPlugin, string pluginName); } } \ No newline at end of file diff --git a/src/Zirconium/Core/Plugins/PluginHostAPI.cs b/src/Zirconium/Core/Plugins/PluginHostAPI.cs index be5f157..3f8b527 100644 --- a/src/Zirconium/Core/Plugins/PluginHostAPI.cs +++ b/src/Zirconium/Core/Plugins/PluginHostAPI.cs @@ -1,7 +1,10 @@ +using System; using System.Collections.Generic; +using System.Threading.Tasks; using Newtonsoft.Json; using Zirconium.Core.Models; using Zirconium.Core.Plugins.Interfaces; +using Zirconium.Core.Plugins.IPC; namespace Zirconium.Core.Plugins { @@ -9,11 +12,13 @@ namespace Zirconium.Core.Plugins { private App _app; private Router _router; + private IPCRouter _ipcRouter; public PluginHostAPI(App app, Router router) { _router = router; _app = app; + _ipcRouter = new IPCRouter(); } public IExposedSessionManager GetSessionManager() { @@ -78,5 +83,18 @@ namespace Zirconium.Core.Plugins { _router.RemoveCoreEventHandler(handler.GetHandlingEventType(), handler); } + + public void RegisterIPCService(IPluginAPI plugin, dynamic service) + { + _ipcRouter.RegisterIPCService(plugin.GetPluginUniqueName(), service); + } + + public Task MakeIPCRequest(string pluginName, string methodName, dynamic paramsObject) { + return _ipcRouter.MakeRequest(pluginName, methodName, paramsObject); + } + + public Task MakeIPCNotification(string pluginName, string methodName, dynamic paramsObject) { + return _ipcRouter.MakeNotif(pluginName, methodName, paramsObject); + } } } \ No newline at end of file diff --git a/src/Zirconium/Core/Plugins/PluginManager.cs b/src/Zirconium/Core/Plugins/PluginManager.cs index 702b150..f555aa9 100644 --- a/src/Zirconium/Core/Plugins/PluginManager.cs +++ b/src/Zirconium/Core/Plugins/PluginManager.cs @@ -8,6 +8,7 @@ using McMaster.NETCore.Plugins; using Zirconium.Core.Logging; using Zirconium.Core.Models; using Zirconium.Core.Plugins.Interfaces; +using Zirconium.Core.Plugins.IPC; using Zirconium.Utils; namespace Zirconium.Core.Plugins @@ -73,7 +74,8 @@ namespace Zirconium.Core.Plugins typeof(IC2SMessageHandler), typeof(ICoreEventHandler), typeof(BaseMessage), - typeof(CoreEvent) + typeof(CoreEvent), + typeof(ExportedIPCMethodAttribute) }, config => config.PreferSharedTypes = true ); @@ -92,28 +94,18 @@ namespace Zirconium.Core.Plugins // This assumes the implementation of IPlugin has a parameterless constructor plugin = (IPluginAPI)Activator.CreateInstance(pluginType); Logging.Log.Debug($"Created plugin instance '{plugin.GetPluginUniqueName()}'."); - var exportedTypes = plugin.GetExportedTypes(); - if (exportedTypes != null) - { - foreach (var type in exportedTypes) - { - var path = new Uri(type.Module.Assembly.CodeBase).LocalPath; - AssemblyLoadContext.Default.LoadFromAssemblyPath(path); - } - } plugin.PreInitialize(this); plugin.Initialize(_pluginHostAPI); } return plugin; } - public dynamic Depends(IPluginAPI currentPlugin, string pluginName) + public void Depends(IPluginAPI currentPlugin, string pluginName) { var dependantPlugin = _plugins.GetValueOrDefault(pluginName, null); - if (dependantPlugin != null) return dependantPlugin.GetExportedAPI(); + if (dependantPlugin != null) return; this.LoadPlugin(pluginName); dependantPlugin = _plugins[pluginName]; - return dependantPlugin.GetExportedAPI(); } } } \ No newline at end of file diff --git a/src/ZirconiumPlugins/MongoDB/Plugin.cs b/src/ZirconiumPlugins/MongoDB/Plugin.cs index 203c28f..68ed0a5 100644 --- a/src/ZirconiumPlugins/MongoDB/Plugin.cs +++ b/src/ZirconiumPlugins/MongoDB/Plugin.cs @@ -1,8 +1,10 @@ -using System.Collections.Immutable; +using System; +using System.Collections.Immutable; using System.Collections.Generic; using Zirconium.Core.Plugins.Interfaces; using MongoDB.Driver; using Zirconium.Core.Logging; +using Zirconium.Core.Plugins.IPC; namespace MongoDBPlugin { @@ -10,18 +12,6 @@ namespace MongoDBPlugin { private IMongoDatabase _database; - public dynamic GetExportedAPI() - { - return _database; - } - - public System.Type[] GetExportedTypes() - { - // var mongoCore = Assembly.Load("MongoDB.Driver.Core"); - // var mongoBson = Assembly.Load("MongoDB.Bson"); - return new System.Type[] {typeof(IMongoDatabase)}; - } - public string GetPluginUniqueName() { return "MongoDB"; @@ -30,13 +20,13 @@ namespace MongoDBPlugin public void Initialize(IPluginHostAPI pluginHostAPI) { var settingsDynamic = pluginHostAPI.GetSettings(this); - var settings = (IImmutableDictionary) ((IDictionary)settingsDynamic).ToImmutableDictionary(); + var settings = (IImmutableDictionary)((IDictionary)settingsDynamic).ToImmutableDictionary(); - var host = (string) settings.GetValueOrDefault("Host"); - var port = (int) settings.GetValueOrDefault("Port"); - var user = (string) settings.GetValueOrDefault("User"); - var password = (string) settings.GetValueOrDefault("Password"); - var database = (string) settings.GetValueOrDefault("Database"); + var host = (string)settings.GetValueOrDefault("Host"); + var port = (int)settings.GetValueOrDefault("Port"); + var user = (string)settings.GetValueOrDefault("User"); + var password = (string)settings.GetValueOrDefault("Password"); + var database = (string)settings.GetValueOrDefault("Database"); MongoClient client; if (user == null && password == null) @@ -51,8 +41,25 @@ namespace MongoDBPlugin var db = client.GetDatabase(database); Log.Info("MongoDB is connected"); _database = db; + var ipcService = new IPCService(db); + pluginHostAPI.RegisterIPCService(this, ipcService); } public void PreInitialize(IPluginManager pluginManager) { } + + class IPCService + { + private IMongoDatabase _db; + + public IPCService(IMongoDatabase db) { _db = db; } + + [ExportedIPCMethod("Insert")] + public void Insert(dynamic paramsObject) { + var colName = paramsObject.ColName; + var model = paramsObject.Model; + _db.GetCollection(colName).InsertOne(model); + Log.Debug("successfully inserted the document"); + } + } } } diff --git a/src/ZirconiumPlugins/TestMongoDB/Plugin.cs b/src/ZirconiumPlugins/TestMongoDB/Plugin.cs index f6d90a0..2beb538 100644 --- a/src/ZirconiumPlugins/TestMongoDB/Plugin.cs +++ b/src/ZirconiumPlugins/TestMongoDB/Plugin.cs @@ -1,52 +1,29 @@ -using Zirconium.Core.Plugins.Interfaces; -using MongoDB.Driver; -using Zirconium.Core.Logging; -using System; +using System.Dynamic; +using Zirconium.Core.Plugins.Interfaces; namespace TestMongoDB { class Plugin : IPluginAPI { - private IMongoDatabase _database; - - public dynamic GetExportedAPI() - { - return null; - } - - public Type[] GetExportedTypes() - { - return null; - } public string GetPluginUniqueName() { return "TestMongoDB"; } - public void Initialize(IPluginHostAPI pluginHostAPI) + public async void Initialize(IPluginHostAPI pluginHostAPI) { var tm = new TestModel(); tm.ABC = "qweqowie"; - _database.GetCollection("test_model").InsertOne(tm); + dynamic paramsObject = new ExpandoObject(); + paramsObject.ColName = "test_model"; + paramsObject.Model = tm; + await pluginHostAPI.MakeIPCRequest("MongoDB", "Insert", paramsObject); } public void PreInitialize(IPluginManager pluginManager) { - var db = pluginManager.Depends(this, "MongoDB"); - var receivedType = db.GetType(); - Log.Debug(db.GetType().FullName); - Log.Debug(db.GetType().AssemblyQualifiedName); - foreach (Type i in db.GetType().GetInterfaces()) { - Log.Debug("DB object interface: " + i.AssemblyQualifiedName); - } - Log.Debug("Type info in current assembly context:"); - var mongoDBType = typeof(IMongoDatabase); - Log.Debug(mongoDBType.FullName); - Log.Debug(mongoDBType.AssemblyQualifiedName); - Log.Debug(new Uri(mongoDBType.Module.Assembly.CodeBase).LocalPath); - Log.Debug($"Casting compatibility: {mongoDBType.IsAssignableFrom(db.GetType())}"); - _database = (IMongoDatabase) db; + pluginManager.Depends(this, "MongoDB"); } } diff --git a/src/ZirconiumPlugins/TestMongoDB/TestMongoDB.csproj b/src/ZirconiumPlugins/TestMongoDB/TestMongoDB.csproj index 70eb03f..816d99c 100644 --- a/src/ZirconiumPlugins/TestMongoDB/TestMongoDB.csproj +++ b/src/ZirconiumPlugins/TestMongoDB/TestMongoDB.csproj @@ -8,8 +8,6 @@ runtime - -