从 DLL 调用主程序方法
Calling Main Program Method from DLL
我有一个主程序动态加载 DLL 文件并激活一个包含所有核心操作的 class 文件,假设 class 继承和插件接口。
我在主窗体上有两个方法,我通过插件接口作为 Action 传递,我在程序集加载期间将这些方法分配给插件中的 Action,然后我调用这些 Actions 并传递一个值从主程序执行方法并执行其任务。
我想知道的是,除了使用 Action/Func 委托之外,是否还有其他替代方法,而不引用主程序(两者必须保持独立,仅与另一个 IPlugin 接口相关主程序和插件项目中引用的 DLL)并且不在插件 DLL 文件本身中使用任何方法调用。
还是我已经在使用最合适的方法?
--编辑--
//Interface
interface IPlugin
{
Action<string> myAction;
}
//Main Program
public class MainForm
{
void LoadPlugins(Action<string> myMethod)
{
List<Assembly> Assemblies = new List<Assembly>();
foreach (string file in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll")) { Assemblies.Add(Assembly.LoadFile(file)); }
foreach (Assembly a in Assemblies)
{
AppDomain.CurrentDomain.Load(a.GetName());
foreach (Type x in a.GetTypes())
{
if (x.IsInterface || x.IsAbstract || x.GetInterface(typeof(IPlugin).FullName) == null) { continue; }
IPlugin plugin = (IPlugin)Activator.CreateInstance(x);
plugin.myAction = myMethod;
}
}
}
void OnLoad()
{
LoadPlugins(UpdateGUI);
}
void UpdateGUI(string Message)
{
txtBlockReport.Text += Message;
}
}
//Plugin compiled as DLL, implementing & referencing IPlugin Interface.
public class MyPlugin : IPlugin
{
public Action<string> myAction { get; set; }
void OnLoad()
{
myAction("Plugin Loaded");
}
}
您可以定义一个 "Host" 接口,在其中包含方法,然后将其传递到插件中。
或者,您可以使用仅包含委托签名的共享源文件(因此没有引用也没有依赖),这基本上就是您在使用 Func
时所做的,只有您可以做到更精确,更好命名。
我已经从界面中删除了一些自行决定的操作,而是在 class(在插件界面 DLL 文件中)中静态创建了一个自定义事件处理程序,以接收程序和插件的更新.
我有一个主程序动态加载 DLL 文件并激活一个包含所有核心操作的 class 文件,假设 class 继承和插件接口。
我在主窗体上有两个方法,我通过插件接口作为 Action 传递,我在程序集加载期间将这些方法分配给插件中的 Action,然后我调用这些 Actions 并传递一个值从主程序执行方法并执行其任务。
我想知道的是,除了使用 Action/Func 委托之外,是否还有其他替代方法,而不引用主程序(两者必须保持独立,仅与另一个 IPlugin 接口相关主程序和插件项目中引用的 DLL)并且不在插件 DLL 文件本身中使用任何方法调用。
还是我已经在使用最合适的方法?
--编辑--
//Interface
interface IPlugin
{
Action<string> myAction;
}
//Main Program
public class MainForm
{
void LoadPlugins(Action<string> myMethod)
{
List<Assembly> Assemblies = new List<Assembly>();
foreach (string file in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll")) { Assemblies.Add(Assembly.LoadFile(file)); }
foreach (Assembly a in Assemblies)
{
AppDomain.CurrentDomain.Load(a.GetName());
foreach (Type x in a.GetTypes())
{
if (x.IsInterface || x.IsAbstract || x.GetInterface(typeof(IPlugin).FullName) == null) { continue; }
IPlugin plugin = (IPlugin)Activator.CreateInstance(x);
plugin.myAction = myMethod;
}
}
}
void OnLoad()
{
LoadPlugins(UpdateGUI);
}
void UpdateGUI(string Message)
{
txtBlockReport.Text += Message;
}
}
//Plugin compiled as DLL, implementing & referencing IPlugin Interface.
public class MyPlugin : IPlugin
{
public Action<string> myAction { get; set; }
void OnLoad()
{
myAction("Plugin Loaded");
}
}
您可以定义一个 "Host" 接口,在其中包含方法,然后将其传递到插件中。
或者,您可以使用仅包含委托签名的共享源文件(因此没有引用也没有依赖),这基本上就是您在使用 Func
时所做的,只有您可以做到更精确,更好命名。
我已经从界面中删除了一些自行决定的操作,而是在 class(在插件界面 DLL 文件中)中静态创建了一个自定义事件处理程序,以接收程序和插件的更新.