【问题标题】:Reflection: Create instance of a class that inherit from another class located in separate assembly反射:创建从位于单独程序集中的另一个类继承的类的实例
【发布时间】:2022-01-15 15:33:50
【问题描述】:

我创建了一个在 .Net Framework 4.7.2 下运行的空 Web 表单应用程序,并创建了一个 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";
        }
    }
}

和:

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:'无法从程序集'System.Web,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a'加载类型'System.Web.UI.Page'。'

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

【问题讨论】:

    标签: c# .net .net-core reflection c#-7.0


    【解决方案1】:

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

    但是,您仍然可以将类 WebApplication1.WebForm1 的元数据加载到 reflection-only context 中,以检查类型。您在 .NET 5 中执行此操作的方式与 .NET Framework 不同,方法是使用来自此 NuGet packageMetadataLoadContext

    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
    

    【讨论】:

      【解决方案2】:

      您通过在.NET Core 上的反射加载在.NET Framework 中构建的程序集,但System.Web 命名空间中的某些类在.NET Core 中不受支持。它加载用户代码部分。其他部分可能无法正常工作。在您的情况下,为.NET Framework 编译的代码的请求类不是.NET Core 的一部分。 System.Web 用于 Asp.Net,在 .NET Core 中存在 System.Web 命名空间,从技术上讲可以调用,但它不会像你想要的那样工作。

      【讨论】:

        猜你喜欢
        • 2019-01-02
        • 1970-01-01
        • 2018-10-06
        • 1970-01-01
        • 1970-01-01
        • 2011-12-08
        • 1970-01-01
        • 2016-08-25
        • 1970-01-01
        相关资源
        最近更新 更多