Type.GetInterface返回null

时间:2013-02-07 17:31:27

标签: c# types system.reflection

我的问题是,我从历史记录中获得了与旧版DLL不同的结果,但很少有变化,而且我没有根据所显示的错误与变更的相关性。

这是我们的SecurityPluginServices.dll模块中方法的一部分,它基本上将插件添加到列表中,以便主程序可以使用它们。

它将所有DLL放在一个set文件夹中,然后为每个DLL运行下面的代码。

private void AddPlugin(string FileName, LoggingUtilities.Source source)
{
    //Create a new assembly from the plugin file we're adding..
    Assembly pluginAssembly = Assembly.LoadFrom(FileName);

    try
    {
        //Next we'll loop through all the Types found in the assembly
        foreach (Type pluginType in pluginAssembly.GetTypes())
        {
            if (pluginType.IsPublic) //Only look at public types
            {
                if (!pluginType.IsAbstract)  //Only look at non-abstract types
                {
                    //Gets a type object of the interface we need the plugins to match
                    Type typeInterface = pluginType.GetInterface("SecurityInterface.ISecurityPlugin", true);

                    //Make sure the interface we want to use actually exists
                    if (typeInterface != null)
                    {
                     // Do work here
                    }

                    typeInterface = null; //Mr. Clean           
                }
            }
        }

        pluginAssembly = null; //more cleanup
    }
    catch (ReflectionTypeLoadException ex1)
    {
        Console.WriteLine(ex1.Message);
    }
    catch (Exception ex2)
    {
        Console.WriteLine(ex2.Message);
    }
}

我遇到的问题是,每当它到达Type typeInterface = pluginType.GetInterface("SecurityInterface.ISecurityPlugin", true);时,它总是返回null。 我需要加载的插件用于NTLM和LDAP,它们在许多版本中的变化很小,只添加了几个额外的属性和方法,与工具的接口无关。 我已经在ILDASM中打开了一个较新的插件DLL和一个较旧的插件,它们似乎都包含有关SecurityInterface.ISecurityPlugin方法所寻求的.GetInterface的相同信息。

Newer LdapSecurity

Older LdapSecurity

2 个答案:

答案 0 :(得分:2)

<强>建议:

Type typeInterface = pluginType.GetInterface("SecurityInterface.ISecurityPlugin", true);
                                          // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

将其更改为fully-qualified type name,即包含包含您的界面类型的程序集的文件。

(如果你现在说你有两个不同类型的同名,在两个不同的程序集中,因此不能包含一个明确的程序集名称,这可能很可能你的问题的原因。)

<强>解释

我的另一个答案让我怀疑可能导致你的问题。一般来说,typeof(T)会强制您为包含T的程序集添加项目的程序集引用。否则,编译将失败。另一方面,类型名称(如Type.GetType("T"))的文本提及不强制执行编译时程序集引用...但它们仍然必须在运行时解析为类型实例。因此,如果省略程序集名称,则需要记住.NET如何将T映射到特定程序集。

回到你的问题。首先,请注意您没有使用完全限定的类型名称:

Type typeInterface = pluginType.GetInterface("SecurityInterface.ISecurityPlugin", true);
                                          // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

您只指定命名空间和类型名称,但不指定包含接口类型的程序集。可能是接口类型被定义了不止一次,即在不同的程序集中,你提到的那个类型名称被解析为输入错误的程序集?

让我们简要地看一下MSDN documentation for Type.GetType(string) method,它描述了字符串参数,如下所示:

  

“要获取的类型的程序集限定名称。[...]如果类型位于当前正在执行的程序集中或Mscorlib.dll中,则提供由其名称空间限定的类型名称就足够了。“

如果同样适用于您使用的Type.GetInterface(string, bool)方法,该怎么办?如果您当前正在执行的程序集 包含该名称的类型,该怎么办?然后,这将是pluginType将被检查的类型...但它可能是一个不同的ISecurityPlugin接口类型(尽管名称相同),而不是插件类实际实现的类型。

答案 1 :(得分:1)

  

更新:请先查看我的其他答案,这可能更相关。

如果您想检查pluginType是否实现ISecurityPlugin界面,您可以执行此检查:

typeof(SecurityInterface.ISecurityPlugin).IsAssignableFrom(pluginType)

如果您没有引用包含ISecurityPlugin的程序集,则可以用Type.GetType("SecurityInterface.ISecurityPlugin")替换第一部分。