我的问题是,我从历史记录中获得了与旧版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
的相同信息。
答案 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")
替换第一部分。