Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.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#_Interface_Plugin Architecture - Fatal编程技术网

C# 具有接口的插件体系结构;接口检查不需要';行不通

C# 具有接口的插件体系结构;接口检查不需要';行不通,c#,interface,plugin-architecture,C#,Interface,Plugin Architecture,我正在应用程序中实现一个简单的插件架构。插件需求是使用应用程序和插件引用的*.dll中的接口(IPlugin)定义的。应用程序有一个插件管理器(也在同一个*.dll中),它通过在插件文件夹中查找所有的*.dll来加载插件,加载它们,然后检查插件是否实现了接口。我已经用两种不同的方法进行了检查[之前使用了一个简单的if(plugin是IPlugin)],但是没有一种方法能够识别插件何时实现接口。代码如下: Assembly pluginAssembly = Assembly.LoadFrom(cu

我正在应用程序中实现一个简单的插件架构。插件需求是使用应用程序和插件引用的*.dll中的接口(IPlugin)定义的。应用程序有一个插件管理器(也在同一个*.dll中),它通过在插件文件夹中查找所有的*.dll来加载插件,加载它们,然后检查插件是否实现了接口。我已经用两种不同的方法进行了检查[之前使用了一个简单的if(plugin是IPlugin)],但是没有一种方法能够识别插件何时实现接口。代码如下:

Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
    foreach (Type currType in pluginAssembly.GetTypes())
    {
        if (currType.GetInterfaces().Contains(typeof(IPlugin)))
        {
            // Code here is never executing
            // even when the currType derives from IPlugin
        }
    }                    
}
我曾经测试过一个特定的类名(“Plugin”),但后来我允许它在程序集中的所有类中循环,但没有用。(这是我在别处找到的一个例子。) 为了使这更复杂一些,有两个接口,每个接口实现原始接口(IPluginA、IPluginB)。该插件实际上实现了一个更具体的接口(IPluginB)。然而,我已经尝试过使用插件来实现更通用的接口(IPlugin),但仍然不起作用

[编辑:回应我第一次收到的两个回复]
是的,我试过使用IsAssignableFrom。见下文:

Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
    foreach (Type currType in pluginAssembly.GetTypes())
    {
        if (typeof(IPlugin).IsAssignableFrom(currType))
        {
            string test = "test";
        }
    }
}
您是否尝试过:

typeof(IPlugin).IsAssignableFrom(currType)
此外,类型实现接口,但它们不是从接口派生的。属性和方法显示派生,其中显示派生或实现

编辑:您的程序集是否已签名?它们可能正在加载,并且由于将
类型
对象与
引用equals
进行比较,因此两个并排程序集中的相同类型将完全独立

编辑2:尝试以下操作:

public Type[] LoadPluginsInAssembly(Assembly otherAssembly)
{
    List<Type> pluginTypes = new List<Type>();
    foreach (Type type in otherAssembly.GetTypes())
    {
        // This is just a diagnostic. IsAssignableFrom is what you'll use once
        // you find the problem.
        Type otherInterfaceType =
            type.GetInterfaces()
            .Where(interfaceType => interfaceType.Name.Equals(typeof(IPlugin).Name, StringComparison.Ordinal)).FirstOrDefault();

        if (otherInterfaceType != null)
        {
            if (otherInterfaceType == typeof(IPlugin))
            {
                pluginTypes.Add(type);
            }
            else
            {
                Console.WriteLine("Duplicate IPlugin types found:");
                Console.WriteLine("  " + typeof(IPlugin).AssemblyQualifiedName);
                Console.WriteLine("  " + otherInterfaceType.AssemblyQualifiedName);
            }
        }
    }

    if (pluginTypes.Count == 0)
        return Type.EmptyTypes;

    return pluginTypes.ToArray();
}
public类型[]加载插件程序集(程序集或其他程序集)
{
列表插件类型=新列表();
foreach(otherAssembly.GetTypes()中的类型)
{
//这只是一个诊断。IsAssignableFrom是您将使用的一次
//你会发现问题所在。
类型otherInterfaceType=
type.GetInterfaces()
.Where(interfaceType=>interfaceType.Name.Equals(typeof(IPlugin.Name,StringComparison.Ordinal)).FirstOrDefault();
if(otherInterfaceType!=null)
{
if(otherInterfaceType==typeof(IPlugin))
{
pluginTypes.Add(类型);
}
其他的
{
WriteLine(“找到重复的IPlugin类型:”);
Console.WriteLine(“+typeof(IPlugin).AssemblyQualifiedName);
Console.WriteLine(“+otherInterfaceType.AssemblyQualifiedName”);
}
}
}
if(pluginTypes.Count==0)
return Type.EmptyTypes;
返回pluginTypes.ToArray();
}

方法IsAssignableFrom就是您要查找的:

Type intType = typeof(IInterface);
foreach (Type t in pluginAssembly.GetTypes())
{
    if (intType.IsAssignableFrom(t))
    {
    }
}

我尝试过使用IsAssignableFrom,但它也不起作用。请参阅原始问题中的编辑。我认为程序集没有签名(GAC)。OP说,他正在尝试从插件文件夹加载它。它们没有签名(不在GAC中)。什么?我根本没说GAC。我在我的集会上签名,但我不可能把他们放进GAC。没关系,我只是想办法。对于其他人:右键单击引用并将Copy Local更改为false。我已经尝试使用IsAssignableFrom,但它也不起作用。请参阅原始问题中的编辑。较大的代码示例将有助于理解实际问题。我非常确定IsAssignableFrom在我的应用程序中为我工作,正如我写这篇文章时所预期的那样。请检查currFile是否是包含插件的DLL,并查看插件程序集中每种类型的currType。currFile是包含插件的*.DLL,currType是(程序集中唯一的类型),这是一个实现IPlugin的插件。换句话说,这些都是正确的。还有其他想法吗?是否应该是:if(currType.IsAssignableFrom(typeof(IPlugin))您正在测试IPlugin的类型是否可以从插件的类型中分配。您应该测试您的插件的类型是否可以从IPlugin中分配?克里斯托弗,280Z28的回复中的代码是正确的。我相信您应该这样想:我可以分配类型的istnace吗(这是该方法的参数)对于.IsAssignableFrom.之前类型的实例,MSDN文章以几种不同的方式说明了这一点(技术上可能比我更正确):