From ec5512ff6b6b92c3e0fdb8e99ac45e8de6fba7ac Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 21 Sep 2020 22:15:04 +0400 Subject: [PATCH 1/3] Change debug log color in Logger --- src/Zirconium/Core/Logging/Logger.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Zirconium/Core/Logging/Logger.cs b/src/Zirconium/Core/Logging/Logger.cs index adb1ec4..55dc0c1 100644 --- a/src/Zirconium/Core/Logging/Logger.cs +++ b/src/Zirconium/Core/Logging/Logger.cs @@ -77,7 +77,7 @@ namespace Zirconium.Core.Logging break; } case LogType.Debug: { - tagFormatter = new Formatter("DEBUG", Color.Lime); + tagFormatter = new Formatter("DEBUG", Color.LightGray); break; } default: { From d14a058d41022973559c415113eea3f41f47b5cf Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 21 Sep 2020 22:17:17 +0400 Subject: [PATCH 2/3] Implement non-working type sharing between plugins --- .../Core/Plugins/Interfaces/IPluginAPI.cs | 3 +++ src/Zirconium/Core/Plugins/PluginManager.cs | 23 +++++++++++++++---- .../HelloWorldPlugin/HelloWorldPlugin.cs | 8 ++++++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Zirconium/Core/Plugins/Interfaces/IPluginAPI.cs b/src/Zirconium/Core/Plugins/Interfaces/IPluginAPI.cs index 8f19337..d772d76 100644 --- a/src/Zirconium/Core/Plugins/Interfaces/IPluginAPI.cs +++ b/src/Zirconium/Core/Plugins/Interfaces/IPluginAPI.cs @@ -1,3 +1,5 @@ +using System; + namespace Zirconium.Core.Plugins.Interfaces { public interface IPluginAPI @@ -6,5 +8,6 @@ namespace Zirconium.Core.Plugins.Interfaces void PreInitialize(IPluginManager pluginManager); string GetPluginUniqueName(); dynamic GetExportedAPI(); + Type[] GetExportedTypes(); } } \ No newline at end of file diff --git a/src/Zirconium/Core/Plugins/PluginManager.cs b/src/Zirconium/Core/Plugins/PluginManager.cs index f162971..702b150 100644 --- a/src/Zirconium/Core/Plugins/PluginManager.cs +++ b/src/Zirconium/Core/Plugins/PluginManager.cs @@ -2,8 +2,10 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.Loader; using System.Threading; using McMaster.NETCore.Plugins; +using Zirconium.Core.Logging; using Zirconium.Core.Models; using Zirconium.Core.Plugins.Interfaces; using Zirconium.Utils; @@ -54,7 +56,7 @@ namespace Zirconium.Core.Plugins public IPluginAPI LoadPlugin(string pluginName) { PluginLoader loader; - var pluginDll = Path.Combine(_currentPluginFolderPath, pluginName + ".dll"); + var pluginDll = Path.Combine(_currentPluginFolderPath, pluginName, pluginName + ".dll"); if (File.Exists(pluginDll)) { Logging.Log.Debug("Found plugin " + pluginName); @@ -62,6 +64,7 @@ namespace Zirconium.Core.Plugins loader = PluginLoader.CreateFromAssemblyFile( pluginDll, sharedTypes: new[] { + typeof(Log), typeof(IPluginAPI), typeof(IPluginHostAPI), typeof(IPluginManager), @@ -71,7 +74,8 @@ namespace Zirconium.Core.Plugins typeof(ICoreEventHandler), typeof(BaseMessage), typeof(CoreEvent) - } + }, + config => config.PreferSharedTypes = true ); } else @@ -79,15 +83,24 @@ namespace Zirconium.Core.Plugins throw new Exception("specified plugin is not found"); } + var pluginTypes = loader.LoadDefaultAssembly().GetTypes(); + IPluginAPI plugin = null; - foreach (var pluginType in loader - .LoadDefaultAssembly() - .GetTypes() + foreach (var pluginType in pluginTypes .Where(t => typeof(IPluginAPI).IsAssignableFrom(t) && !t.IsAbstract)) { // 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); } diff --git a/src/ZirconiumPluginExamples/HelloWorldPlugin/HelloWorldPlugin.cs b/src/ZirconiumPluginExamples/HelloWorldPlugin/HelloWorldPlugin.cs index 1c67ff6..61e7b2e 100644 --- a/src/ZirconiumPluginExamples/HelloWorldPlugin/HelloWorldPlugin.cs +++ b/src/ZirconiumPluginExamples/HelloWorldPlugin/HelloWorldPlugin.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using System; +using Newtonsoft.Json; using Zirconium.Core.Logging; using Zirconium.Core.Models; using Zirconium.Core.Plugins.Interfaces; @@ -19,6 +20,11 @@ namespace HelloWorldPlugin public void PreInitialize(IPluginManager pluginManager) { } public dynamic GetExportedAPI() { return null; } + + public Type[] GetExportedTypes() + { + return null; + } } internal class C2SHandler : IC2SMessageHandler From a829042581e294c4fc7cfa71e4074e8ca056852f Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 21 Sep 2020 22:18:31 +0400 Subject: [PATCH 3/3] Implement two example plugins (MongoDB connection wrapper and consumer of this conn wrapper) which is sharing types between them --- src/ZirconiumPlugins/MongoDB/MongoDB.csproj | 16 +++++ src/ZirconiumPlugins/MongoDB/Plugin.cs | 58 +++++++++++++++++++ src/ZirconiumPlugins/TestMongoDB/Plugin.cs | 57 ++++++++++++++++++ .../TestMongoDB/TestMongoDB.csproj | 15 +++++ 4 files changed, 146 insertions(+) create mode 100644 src/ZirconiumPlugins/MongoDB/MongoDB.csproj create mode 100644 src/ZirconiumPlugins/MongoDB/Plugin.cs create mode 100644 src/ZirconiumPlugins/TestMongoDB/Plugin.cs create mode 100644 src/ZirconiumPlugins/TestMongoDB/TestMongoDB.csproj diff --git a/src/ZirconiumPlugins/MongoDB/MongoDB.csproj b/src/ZirconiumPlugins/MongoDB/MongoDB.csproj new file mode 100644 index 0000000..932a2a2 --- /dev/null +++ b/src/ZirconiumPlugins/MongoDB/MongoDB.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.1 + + + + + runtime + + + + + + + diff --git a/src/ZirconiumPlugins/MongoDB/Plugin.cs b/src/ZirconiumPlugins/MongoDB/Plugin.cs new file mode 100644 index 0000000..203c28f --- /dev/null +++ b/src/ZirconiumPlugins/MongoDB/Plugin.cs @@ -0,0 +1,58 @@ +using System.Collections.Immutable; +using System.Collections.Generic; +using Zirconium.Core.Plugins.Interfaces; +using MongoDB.Driver; +using Zirconium.Core.Logging; + +namespace MongoDBPlugin +{ + class Plugin : IPluginAPI + { + 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"; + } + + public void Initialize(IPluginHostAPI pluginHostAPI) + { + var settingsDynamic = pluginHostAPI.GetSettings(this); + 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"); + + MongoClient client; + if (user == null && password == null) + { + client = new MongoClient($"mongodb://{host}:{port}"); + } + else + { + client = new MongoClient($"mongodb://{user}:{password}@{host}:{port}"); + } + + var db = client.GetDatabase(database); + Log.Info("MongoDB is connected"); + _database = db; + } + + public void PreInitialize(IPluginManager pluginManager) { } + } +} diff --git a/src/ZirconiumPlugins/TestMongoDB/Plugin.cs b/src/ZirconiumPlugins/TestMongoDB/Plugin.cs new file mode 100644 index 0000000..f6d90a0 --- /dev/null +++ b/src/ZirconiumPlugins/TestMongoDB/Plugin.cs @@ -0,0 +1,57 @@ +using Zirconium.Core.Plugins.Interfaces; +using MongoDB.Driver; +using Zirconium.Core.Logging; +using System; + +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) + { + var tm = new TestModel(); + tm.ABC = "qweqowie"; + _database.GetCollection("test_model").InsertOne(tm); + } + + 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; + } + } + + class TestModel + { + public string ABC { get; set; } + } +} diff --git a/src/ZirconiumPlugins/TestMongoDB/TestMongoDB.csproj b/src/ZirconiumPlugins/TestMongoDB/TestMongoDB.csproj new file mode 100644 index 0000000..70eb03f --- /dev/null +++ b/src/ZirconiumPlugins/TestMongoDB/TestMongoDB.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp3.1 + + + + + runtime + + + + + +