反思:创建一个 class 的实例,它继承自位于单独程序集中的另一个 class

Reflection: Create instance of a class that inherit from another class located in separate assembly

我在 .Net Framework 4.7.2 下创建了一个 运行 的空 Web 表单应用程序,并创建了一个 Web 表单和一个名为 MyClass:

的 class
namespace WebApplication1
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        public string GetText()
        {
            return "Message of Web Form 1";
        }
    }
}

和:

namespace WebApplication1
{
    public class MyClass
    {
        public string GetText()
        {
           return "Message from MyClass";
        }
    }
}

我使用“将所有程序集合并为一个程序集”选项发布它:

然后我想获取类型,然后创建 WebForm1MyClass 的实例。

我在 控制台应用程序中编写了这段代码 运行 在 .Net 5:

Assembly asm = Assembly.LoadFrom(@"C:\Pub\bin\WebApplication1.dll");

Type tMyClass = asm.GetType("WebApplication1.MyClass");
Type t = asm.GetType("WebApplication1.WebForm1"); <----Error

代码有运行后,tMyClass有正确的类型:

]

但是当我尝试获取 WebForm1 的类型时,出现错误:

System.TypeLoadException: 'Could not load type 'System.Web.UI.Page' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.'

如何获取 WebForm1 的类型并创建它的实例?

您通过 .NET Core 上的反射加载了 .NET Framework 中内置的程序集,但是 .NET Core 不支持 System.Web 命名空间中的某些 classes ].它加载用户代码部分。其他部分可能不起作用。在您的情况下,为 .NET Framework 编译的代码的请求 class 不是 .NET Core 的一部分。 System.Web 用于 Asp.Net,在 .NET Core 中,System.Web 命名空间存在并且在技术上可以调用,但它不会像您想要的那样工作。

错误的原因是因为 System.Web.UI.Page 在 .NET 5 中不存在。因此您无法加载程序集以在控制台应用程序中执行代码。

但是,您仍然可以在 reflection-only context for the purpose of examining the type. The way you do it in .NET 5 is different than .NET Framework by using a MetadataLoadContext from this NuGet package.

中加载 class WebApplication1.WebForm1 的元数据
var dllPath = @"C:\Pub\bin\WebApplication1.dll";

var paths = new List<string>();
paths.AddRange(Directory.GetFiles(Path.GetDirectoryName(dllPath), "*.dll"));
paths.AddRange(Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll"));

using var context = new MetadataLoadContext(new PathAssemblyResolver(paths));
var asm = context.LoadFromAssemblyPath(dllPath);
var yourType = asm.GetType("WebApplication1.WebForm1");

另请注意,如果您尝试访问在未加载的程序集中定义的方法,您仍然会收到错误消息:

yourType.GetMethods(); // Error
yourType.GetMethods(BindingFlags.DeclaredOnly); // OK