-
Автор темы
- #1
Простая система плагинов на .NET 5, вдруг кому пригодиться, чуть-чуть копипасты
Не судите строго:)
Здесь мы берем дллки из папки и записываем в память приложения.
C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace PluginSystem
{
public class PluginLoader
{
public static List<IPlugin> Plugins { get; set; }
public void LoadPlugins(Dictionary<object, object>[] configDict)
{
Plugins = new List<IPlugin>();
//Загружает дллки из папки
if (Directory.Exists("Plugins"))
{
string[] files = Directory.GetFiles("Plugins");
foreach (string file in files)
{
if (file.EndsWith(".dll"))
{
Assembly.LoadFile(Path.GetFullPath(file));
}
}
}
Type interfaceType = typeof(IPlugin);
//Получаем все типы, которые реализуют интерфейс IPlugin и являются классами
Type[] types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(asm => asm.GetTypes())
.Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass)
.ToArray();
//Запихиваем экземпляры классов, которые указаны в конфиге, в список.
foreach (Dictionary<object, object> config in configDict)
{
foreach (Type type in types)
{
if (config["ConnectionName"].ToString() == type.Name)
{
Plugins.Add((IPlugin)Activator.CreateInstance(type, new object[] { config }));
}
}
}
}
}
}
Реализация интерфейса IPlugin
Нужно писать дллки, которые реализуют данный интерфейс, чтобы движок понимал, какой именно класс нужно загружать в память
Нужно писать дллки, которые реализуют данный интерфейс, чтобы движок понимал, какой именно класс нужно загружать в память
C#:
using System.Threading.Tasks;
namespace PluginSystem
{
public interface IPlugin
{
public string Name { get; }
Task SomeFunc1();
Task SomeFunc2();
Task Save();
Task Update();
Task Delete();
}
}
C#:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace PluginSystem
{
class Program
{
// Конфиг
private static Dictionary<object, object>[] ConfigDictionary { get; set; }
static async Task Main(string[] args)
{
// Проверка на null
if (ConfigDictionary != null)
{
try
{
// Создаём экземпляр объекта PluginLoader
PluginLoader loader = new PluginLoader();
//Передаём в объект конфиг
loader.LoadPlugins(ConfigDictionary);
}
catch (Exception e)
{
_logger.LogError($"Plugins couldn't be loaded: {e.Message}");
}
}
// Записываем в список наши экземпляры классов дллок
List<IPlugin> plugins = PluginLoader.Plugins;
if (plugins != null)
{
foreach (var plugin in plugins)
{
await plugin.Save();
await plugin.Delete();
await plugin.SomeFunc1();
}
}
else
{
_logger.LogWarning($"No plugins found");
}
}
}
}
}