C# 从DLL调用主程序方法

C# 从DLL调用主程序方法,c#,methods,delegates,C#,Methods,Delegates,我有一个主程序,它动态加载DLL文件,并激活一个包含所有核心操作的类文件,假定类继承和插件接口 我在主窗体上有两个方法,我通过插件接口将其作为操作传递,我在程序集加载期间将这些方法分配给插件中的操作,然后调用这些操作并传递一个值,该值从主程序执行该方法并执行其任务 我想知道的是,除了使用Action/Func委托之外,是否还有其他替代方法,而不引用主程序(两者必须保持分离,仅通过IPlugin接口相关,IPlugin接口是主程序和插件项目中引用的另一个DLL)并且不使用插件DLL文件本身中调用的

我有一个主程序,它动态加载DLL文件,并激活一个包含所有核心操作的类文件,假定类继承和插件接口

我在主窗体上有两个方法,我通过插件接口将其作为操作传递,我在程序集加载期间将这些方法分配给插件中的操作,然后调用这些操作并传递一个值,该值从主程序执行该方法并执行其任务

我想知道的是,除了使用Action/Func委托之外,是否还有其他替代方法,而不引用主程序(两者必须保持分离,仅通过IPlugin接口相关,IPlugin接口是主程序和插件项目中引用的另一个DLL)并且不使用插件DLL文件本身中调用的任何方法

还是我已经在使用最合适的方法

--编辑--

//接口
接口IPlugin
{
行动我的行动;
}
//主程序
公共类主窗体
{
void LoadPlugins(Action myMethod)
{
列表程序集=新列表();
foreach(Directory.GetFiles(Directory.GetCurrentDirectory(),“*.dll”)中的字符串文件){Assemblies.Add(Assembly.LoadFile(file));}
foreach(部件中的部件a)
{
AppDomain.CurrentDomain.Load(a.GetName());
foreach(在a.GetTypes()中键入x)
{
if(x.IsInterface | | | x.IsAbstract | | | x.GetInterface(typeof(IPlugin).FullName)==null){continue;}
IPlugin插件=(IPlugin)Activator.CreateInstance(x);
plugin.myAction=myMethod;
}
}
}
void OnLoad()
{
LoadPlugins(UpdateGUI);
}
void UpdateGUI(字符串消息)
{
txtBlockReport.Text+=消息;
}
}
//编译为DLL的插件,实现并引用IPlugin接口。
公共类MyPlugin:IPlugin
{
公共操作myAction{get;set;}
void OnLoad()
{
myAction(“插件加载”);
}
}
您可以定义一个“主机”接口,在那里有方法,并将其传递到插件中

或者,您可以使用只包含委托签名的共享源文件(因此没有引用和依赖关系),这基本上就是您在使用
Func
时所做的,只有您可以使其更精确和更好地命名。

您可以定义一个“主机”接口,在那里有方法,并将其传递到插件中


或者,您可以使用只包含代理签名的共享源文件(因此没有引用也没有依赖项),这基本上就是您在使用
Func
时所做的,只有您可以使它更精确和更好地命名。

我已经从接口中删除了一些自主操作,而是在类中(在插件接口DLL文件中)静态创建了一个自定义事件处理程序,接收程序和插件的更新。

我已经从接口中删除了一些自主操作,而是在类(插件接口DLL文件)中静态创建了一个自定义事件处理程序,以接收程序和插件的更新。

您可以使用主窗体(或其他对象)实现另一个公开这两个方法的接口,并通过这种方式将其传递给插件。主程序有一个实现插件接口的类,我在主窗体中调用接口逻辑按钮。示例:主窗体生成控件并设置要执行的按钮(Button.Tag作为IPlugin)。方法(“参数”);-我本来打算在接口中创建方法并使用相同的方法,但问题是,从逻辑上讲,当我希望DLL文件在主程序中执行一个方法时,我认为它在DLL文件中执行一个方法。@ColinMurphy有太多令人费解的描述性信息。你试试发一些代码怎么样?我已经用示例代码更新了我的主要帖子,说明了我目前正在做的事情,以及我希望做的事情。动作是有效的,但我也在想,在保持两个程序分开的情况下,是否还有其他替代方案可以起作用。您想替换/避免什么?您可以让主窗体(或其他对象)实现另一个接口,该接口公开这两个方法,主程序有一个实现插件接口的类,我在main forms中调用接口逻辑按钮。示例:主窗体生成控件并设置要执行的按钮(Button.Tag作为IPlugin)。方法(“参数”);-我本来打算在接口中创建方法并使用相同的方法,但问题是,从逻辑上讲,当我希望DLL文件在主程序中执行一个方法时,我认为它在DLL文件中执行一个方法。@ColinMurphy有太多令人费解的描述性信息。你试试发一些代码怎么样?我已经用示例代码更新了我的主要帖子,说明了我目前正在做的事情,以及我希望做的事情。操作是有效的,但我也在想,在保持两个程序分开的情况下,是否还有其他替代方案可以发挥作用。您试图替换/避免什么?在这种情况下,主机界面会是什么样子?。我也刚刚回复了我的原始帖子,在我意识到它将是调用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");
    }
}