Type.IsSubclassOf()在AppDomains中不起作用?

时间:2009-01-21 16:33:28

标签: c# reflection types appdomain

我在使用以下代码时遇到了一些问题:

private class ClientPluginLoader : MarshalByRefObject
{
    public bool IsPluginAssembly(string filename)
    {
        AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomainReflectionOnlyAssemblyResolve);

        Assembly asm = Assembly.ReflectionOnlyLoadFrom(filename);

        Type[] types = asm.GetTypes();
        foreach (Type type in types)
        {
            if (type.IsSubclassOf(typeof(ClientPlugin)))
            {
                return true;
            }
        }

        return false;
    }
}

通过我通过自定义应用程序域的CreateInstanceFromAndUnwrap()创建的代理调用代码。这意味着IsPluginAssembly()在我的自定义应用程序域的上下文中执行。

问题是对IsSubclassOf()的调用总是返回false,即使它应该返回true。所讨论的“类型”确实继承自ClientPlugin - 毫无疑问。

ClientPlugin是在一个不同的私有程序集中定义的,我正在手动解析,如上面的代码片段所示。

我在if (type.IsSubclassOf(...))行放了一个断点并确认这个表达式是假的:

type.BaseType == typeof(ClientPlugin)

另一方面,这个表达式是正确的:

type.BaseType.FullName == typeof(ClientPlugin).FullName

这怎么可能?发生了什么事?

更新:Kent Boogaart向我指出了正确的方向。我在网上搜索了一下,然后进入this博文。我似乎必须解决我的Load / LoadFrom / ReflectionOnlyLoadFrom冲突才能使其工作。

2 个答案:

答案 0 :(得分:7)

这是由于加载到不同的上下文。加载程序集的方式(Load / LoadFrom / ReflectionOnlyLoad)确定加载程序集的上下文。这个简单的例子也证明了这个问题:

using System;
using System.Reflection;

class Foo
{
    public static void Main()
    {
        var type = typeof(Foo);
        var reflectionLoadType = Assembly.ReflectionOnlyLoad("ConsoleApplication1").GetType("Foo");
        Console.WriteLine(type == reflectionLoadType);  //false
        Console.WriteLine(type.Equals(reflectionLoadType));  //false

        Console.WriteLine("DONE");
        Console.ReadKey();
    }
}

有关详细信息,请参阅here

答案 1 :(得分:2)

我遇到了类似的问题。我也有这个架构 - 一个包含ClientPlugin基类的.DLL;几个参考这个.DLL的插件;和一个主应用程序,也引用此.DLL。问题是带有ClientPlugin基类的.DLL被复制到两个文件夹中 - Plugins文件夹和主应用程序文件夹。因此它在我的AppDomain中加载了两次(插件也间接加载它)。当主应用程序尝试执行反射类型魔术时,它失败了,因为有两个ClientPlugin类型的实例。

虽然我认为这不是你的情况,但这里还有一个教训 - 如果.DLL加载两次,类型也会重复。在你的情况下,我会怀疑单独的AppDomains,或“ReflectionOnlyLoad”,因为.DLL然后以某种方式加载不同。