Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.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# 从dll加载插件_C#_.net_Plugins_Dll_.net Assembly - Fatal编程技术网

C# 从dll加载插件

C# 从dll加载插件,c#,.net,plugins,dll,.net-assembly,C#,.net,Plugins,Dll,.net Assembly,我已经开始使用一个简单的插件加载器,它监视一个目录,并在其中的dll包含IPlugin接口时加载插件 public class PluginLoader : Dictionary<string, IPlugin> { private FileSystemWatcher watcher; private string pluginPath; public PluginLoader() : base() {

我已经开始使用一个简单的插件加载器,它监视一个目录,并在其中的dll包含IPlugin接口时加载插件

public class PluginLoader : Dictionary<string, IPlugin>
{
    private FileSystemWatcher watcher;
    private string pluginPath;

    public PluginLoader()
        : base()
    {            
        pluginPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "plugins");
        if (!Directory.Exists(pluginPath))
            Directory.CreateDirectory(pluginPath);

        watcher = new FileSystemWatcher(pluginPath, "*.dll");
        watcher.IncludeSubdirectories = true;
        watcher.Created += watcher_Created;
        watcher.EnableRaisingEvents = true;
    }        

    private void watcher_Created(object sender, FileSystemEventArgs e)
    {
        LoadPlugin(e.FullPath);
    }

    private void LoadPlugin(string path)
    {            
        IPlugin plugin = null;
        Assembly assembly = Assembly.LoadFrom(path);

        foreach (Type type in assembly.GetExportedTypes())
        {
            if (type.IsClass && type.GetInterfaces().Count(iType => iType == typeof(IPlugin)) == 1)
            {
                ConstructorInfo constructor = type.GetConstructor(new Type[] { });
                object instance = constructor.Invoke(new object[] { });
                plugin = instance as IPlugin;
                // plugin is now not null
            }
        }
        if (plugin != null && !this.ContainsKey(plugin.PluginName))
        {
            this[plugin.PluginName] = plugin;
        }
    }        
}    
我只是不明白为什么。所以我的问题是:为什么在第二个例子中插件最终是空的

解决方案:
问题是我有两种不同的
IPlugin
类型,因为它的程序集存在于两个不同的位置。因此,删除plugin目录中的
Framework.Lib.dll
解决了这个问题。

我能想到的唯一原因是该类型实现了一个
IPlugin
,它具有相同的名称空间,但来自不同的程序集。
typeof(IPlugin).FullName将在插件加载程序和插件之间匹配,但实现的类型仍然不等于预期的类型

第一个示例与完全相同的类型匹配,在第二个示例中,您通过
FullName
进行匹配,它只包括名称空间,而不包括从中加载类型的程序集

要确定是否是这种情况,请尝试记录以下值:

bool matches = typeof(IPlugin).IsAssignableFrom(type);
string expected = typeof(IPlugin).AssemblyQualifiedName;
string actual = type.GetInterface(typeof(IPlugin).FullName).AssemblyQualifiedName;

typeof(IPlugin)。IsAssignableFrom(type)
可能是您首先要查找的内容。

成功加载插件后,使用
break
停止对其余类型的迭代。预期值等于实际值,但匹配值为false。插件加载器在“Framework”程序集中,IPlugin接口在“Framework.Lib”程序集中,我的测试插件(“test”程序集)引用“Framework.Lib”并实现IPlugin
stringactual=type.GetInterface(typeof(IPlugin).FullName).Location?如果
IsAssignableFrom()
返回false,那么第一个示例也将导致null。示例1中的第一个匹配类型是否与示例2中的第一个匹配类型相同?是的,位置不同。。第一个位置是
\Framework.Lib.dll
,第二个位置是
\plugins\testplugin\Framework.Lib.dll
。你是对的,第一个例子也应该返回false。现在它确实返回false。我也不知道我“弄坏”了什么。如果你从插件目录中删除
Framework.Lib.dll
,它还会运行吗?当然会!现在是语句
type.GetInterface(typeof(IPlugin.FullName)!=null
type.GetInterfaces().Count(iType=>iType==typeof(IPlugin))==1
typeof(IPlugin)。IsAssignableFrom(type)
为真。我想我现在明白了。。谢谢
bool matches = typeof(IPlugin).IsAssignableFrom(type);
string expected = typeof(IPlugin).AssemblyQualifiedName;
string actual = type.GetInterface(typeof(IPlugin).FullName).AssemblyQualifiedName;