Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.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#从文件中添加类而不重新编译_C# - Fatal编程技术网

C#从文件中添加类而不重新编译

C#从文件中添加类而不重新编译,c#,C#,对于一个编程类,我需要编写一个插件管理器,它可以处理实现特定接口(IPlugin)的插件(存储它们并向它们分配需要处理的请求)。我已经做了这件事,到目前为止一切顺利 此外,插件管理器需要能够处理/添加第三方插件,而无需重新编译整个程序。允许重新启动程序 我们的教授建议我们,当重新启动项目时,pluginmanager应该在某个文件夹中查找已经编译的实现IPlugin的类,并将它们添加到活动插件列表中 由于我还没有在互联网上找到任何帮助,我想知道是否有人知道如何做?您可以使用System.Refl

对于一个编程类,我需要编写一个插件管理器,它可以处理实现特定接口(IPlugin)的插件(存储它们并向它们分配需要处理的请求)。我已经做了这件事,到目前为止一切顺利

此外,插件管理器需要能够处理/添加第三方插件,而无需重新编译整个程序。允许重新启动程序

我们的教授建议我们,当重新启动项目时,pluginmanager应该在某个文件夹中查找已经编译的实现IPlugin的类,并将它们添加到活动插件列表中


由于我还没有在互联网上找到任何帮助,我想知道是否有人知道如何做?

您可以使用
System.Reflection
名称空间。它包含在运行时加载.NET程序集所必需的
Assembly
类。但请注意,如果加载非.NET程序集,它将抛出
BadImageFormatException

加载程序集后,可以使用程序集类提供的
GetExportedTypes
方法获取所有公共类型。您必须对它们进行筛选,以检查它们
IPlugin
是否可从该类型分配,以及它是否具有约定的构造函数,例如空的默认构造函数

然后,您可以通过调用
ConstructorInfo
对象上的
Invoke
或使用
Activator
类来创建该类型的实例。两种方法都必须将创建的对象强制转换为
IPlugin
。最后一步是使用接口提供的方法和属性初始化插件

作为奖励,您可以使用
System.IO
命名空间中的
FileSystemWatcher
来监视在指定文件夹中创建的文件。您可以订阅
Created
事件,然后加载程序集。您必须注意,如果属性
EnableRaisingEvents
设置为false,则
FileSystemWatcher
不会调用该事件,这是默认设置

我将为您提供一个示例,但鼓励您首先尝试实现自己的版本

    private void LoadAssembly(string path)
    {
        if (!File.Exists(path))
            throw new ArgumentException($"Could not find the file \"{path}\"");

        try
        {
            Assembly asm = Assembly.LoadFile(path);
            foreach (IPlugin plugin in asm.GetExportedTypes()
                .Where(type => typeof(IPlugin).IsAssignableFrom(type) &&
                               type.GetConstructor(Type.EmptyTypes) != null)
                .Select(type => Activator.CreateInstance(type) as IPlugin))
            {
                plugin.Load();
            }
        }
        catch (Exception ex) when (
            ex is FileLoadException ||
            ex is BadImageFormatException)
        {
            // Do something useful
        }
    }

查找
MEF
依赖项注入
。加载目标目录中的程序集,扫描类型以识别实现插件接口的每种类型。如Amy所建议的。使用反射加载目录(DLL、EXE)中的程序集。查看此链接并阅读备注部分,了解它的意图非常感谢您提供的详细答案:)我将在明天试用,如果对我有效,请在此处报告