2

我的问题是,我从历史中得到了与我们的旧 DLL 不同的结果,当时几乎没有变化,而且我不知道这些变化与显示的错误有什么关系。

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

它在一个集合文件夹中获取所有 DLL,然后对每个 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方法正在寻找的相同信息。

较新的 LdapSecurity

旧版 LdapSecurity

4

2 回答 2

2

建议:

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

将其更改为完全限定的类型名称,即包含包含您的接口类型的程序集的名称。

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

解释:

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

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

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

您只指定命名空间和类型名称,而不是包含您的接口类型的程序集。接口类型是否定义了不止一次,即在不同的程序集中,并且您提到该类型名称被解析为键入错误的程序集?

我们简单看一下method的MSDN文档Type.GetType(string),对字符串参数的描述如下:

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

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

于 2013-02-08T10:15:32.080 回答
1

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

如果要检查是否pluginType实现了ISecurityPlugin接口,可以改为执行此检查:

typeof(SecurityInterface.ISecurityPlugin).IsAssignableFrom(pluginType)

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

于 2013-02-08T09:29:34.000 回答