7

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

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 为我指明了正确的方向。我在网上搜索了更多,然后遇到了这篇博文。看来我必须解决我的 Load/LoadFrom/ReflectionOnlyLoadFrom 冲突才能完成这项工作。

4

2 回答 2

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();
    }
}

请参阅此处了解更多信息。

于 2009-01-21T16:53:54.173 回答
2

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

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

于 2009-01-21T16:43:17.347 回答