Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何让plugin.dll调用核心应用程序的函数?_C#_Plugins_Reflection - Fatal编程技术网

C# 如何让plugin.dll调用核心应用程序的函数?

C# 如何让plugin.dll调用核心应用程序的函数?,c#,plugins,reflection,C#,Plugins,Reflection,好的。所以我想建立一个程序,作为“插件”模块的核心。 另一个开发人员可以创建一个plugin1.dll并将其添加到“modules”文件夹中,以增强我的核心应用程序的功能 因此,让我们假设我的核心具有这些功能: 伐木 用户身份验证 用户界面 例如,我们有上面提到的核心应用程序,有人想添加一个插件,让用户看到当前时间并将其记录到一个standard-log.txt中 因此他将创建一个具有以下功能的类库: public interface ICoreApplication { //The

好的。所以我想建立一个程序,作为“插件”模块的核心。 另一个开发人员可以创建一个plugin1.dll并将其添加到“modules”文件夹中,以增强我的核心应用程序的功能

因此,让我们假设我的核心具有这些功能:

  • 伐木
  • 用户身份验证
  • 用户界面
例如,我们有上面提到的核心应用程序,有人想添加一个插件,让用户看到当前时间并将其记录到一个standard-log.txt中

因此他将创建一个具有以下功能的类库:

public interface ICoreApplication
{
    //These are the methods that you want to provide to your plugins:
    void LogMessage(string msg);
    //void SomeOtherMethod(...)
    //...
}

public interface IPlugin
{
    //These are the methods that you expect from your plugins:
    void Init(ICoreApplication coreReference);
}
public class Core : ICoreApplication
{
    public void InitPlugins()
    {
        IPlugin somePlugin = ...; //retrieve via reflection
        somePlugin.Init(this);
    }
}
  • 获取当前时间(包含在.dll中的功能)
  • 显示当前时间(包含在.dll中的功能)
  • 记录当前时间(核心中包含的功能)
现在我的问题是,我可以使用反射从我的核心应用程序轻松地调用插件的功能,但我该如何反过来呢?
我的plugin1.dll如何访问和调用核心程序的完整设置日志功能

我希望你明白我的问题。我希望我的plugin1.dll能够调用我的核心类的示例日志记录方法


谢谢

我建议将您的问题分为两个方面:

  • 插件如何知道内核中有哪些功能 应用程序(在编译时)
  • 他们如何实际调用这些函数(在运行时)
  • 第一个方面的答案是创建一个单独的接口dll,它定义了核心应用程序将提供的一个(或多个)接口。请注意,这应该只包含接口定义,而不包含实现。插件开发人员随后可以导入该dll,并针对该接口编程(无需依赖于完整的核心实现)

    第二个方面的答案是:您可以要求插件公开一个众所周知的初始化入口点。在该方法中,您可以向它们提供对核心实现的引用作为参数,以便它们可以存储该引用并根据需要在该接口上调用方法

    一个简单的示例可能类似于以下内容:

    接口dll:

    public interface ICoreApplication
    {
        //These are the methods that you want to provide to your plugins:
        void LogMessage(string msg);
        //void SomeOtherMethod(...)
        //...
    }
    
    public interface IPlugin
    {
        //These are the methods that you expect from your plugins:
        void Init(ICoreApplication coreReference);
    }
    
    public class Core : ICoreApplication
    {
        public void InitPlugins()
        {
            IPlugin somePlugin = ...; //retrieve via reflection
            somePlugin.Init(this);
        }
    }
    
    (顺便说一句:如果你知道你希望你的插件提供的功能,IPlugin接口也可以包含其他方法。在这种情况下,你不需要通过反射来调用插件,而是通过这个接口。)

    核心应用程序:

    public interface ICoreApplication
    {
        //These are the methods that you want to provide to your plugins:
        void LogMessage(string msg);
        //void SomeOtherMethod(...)
        //...
    }
    
    public interface IPlugin
    {
        //These are the methods that you expect from your plugins:
        void Init(ICoreApplication coreReference);
    }
    
    public class Core : ICoreApplication
    {
        public void InitPlugins()
        {
            IPlugin somePlugin = ...; //retrieve via reflection
            somePlugin.Init(this);
        }
    }
    
    请注意,这只是一个简单的示例,用于说明基本概念。提供一个健壮的插件架构还有很多。你需要考虑像这样的事情

    • 安全性(你能信任你的插件吗?你能信任你加载它们的文件系统吗?)
    • 错误处理(如果插件抛出异常会发生什么?如果插件想要通知您“预期失败”会发生什么?)
    • 线程(如果在主线程上调用插件,它们可能会阻止整个应用程序。如果在其他线程上调用插件,则需要考虑同步。如果插件创建新线程并在该线程上调用核心应用程序,该怎么办?)
    • 等等

    提供一个带有接口的共享程序集,现在双方都可以处理这些抽象。@Thehenny这也是我的第一个想法。将模块和核心应用程序共享、使用的所有功能移动到由它们全部实现的程序集。不过,我不太确定它将如何工作。你能给我举个简单的例子吗?