反射:创建从位于单独程序集中的另一个类继承的类的实例

Ari*_*ian 1 .net c# reflection .net-core c#-7.0

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

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";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和:

namespace WebApplication1
{
    public class MyClass
    {
        public string GetText()
        {
           return "Message from MyClass";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

然后我想获取类型,然后创建WebForm1and的实例MyClass

我在一个控制台应用程序中编写了这段代码,该应用程序在以下位置运行 .Net 5

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

Type tMyClass = asm.GetType("WebApplication1.MyClass");
Type t = asm.GetType("WebApplication1.WebForm1"); <----Error
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述]

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

在此输入图像描述

System.TypeLoadException:“无法从程序集“System.Web,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”加载类型“System.Web.UI.Page”。”

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

wei*_*hch 5

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

但是,您仍然可以在仅反射上下文WebApplication1.WebForm1中加载类的元数据,以便检查类型。在 .NET 5 中执行此操作的方式与 .NET Framework 中的方式不同,您使用此NuGet 包中的一个。MetadataLoadContext

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");
Run Code Online (Sandbox Code Playgroud)

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

yourType.GetMethods(); // Error
yourType.GetMethods(BindingFlags.DeclaredOnly); // OK
Run Code Online (Sandbox Code Playgroud)