c# - 如何将 XmlIncludeAttribute 应用于 TypeBuilder?

标签 c# .net reflection reflection.emit

我正在用 C# 开发一个库,它使用 System.Reflection.Emit.TypeBuilder 类生成运行时类型,我想生成以下类层次结构:

[XmlInclude(typeof(Derived))]
public class Base
{
}

public class Derived : Base
{
}

我按以下方式使用 TypeBuilder 类:

class Program
{
    public static void Main(string[] args)
    {
        var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.Run);

        var moduleBuilder = assembly.DefineDynamicModule("Test");

        var baseTypeBuilder = moduleBuilder.DefineType("Base", TypeAttributes.Public, typeof(Object));

        var derivedTypeBuilder = moduleBuilder.DefineType("Derived", TypeAttributes.Public);

        derivedTypeBuilder.SetParent(baseTypeBuilder);

        baseTypeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(XmlIncludeAttribute).GetConstructor(new[] { typeof(Type) }), new[] { derivedTypeBuilder }));

        var baseType = baseTypeBuilder.CreateType();

        var derivedType = derivedTypeBuilder.CreateType();

        var attribute = baseType.GetCustomAttribute<XmlIncludeAttribute>();
    }
}

电话:

var attribute = baseType.GetCustomAttribute<XmlIncludeAttribute>();

我收到以下错误:

无法加载文件或程序集 'Test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' 或其依赖项之一。系统找不到指定的文件。

任何想法都很受欢迎:我如何在引用派生类的 TypeBuilder 的基类的 TypeBuilder 上应用自定义属性?

PS:我使用的是 Visual Studio 2017 (v15.7.5) 和 C# 类库(.NET Framework 项目模板)不是 .NET Core 或 .NET Standard

最佳答案

无法提供太多理由,但可以提供一个无需额外加载/卸载或任何从磁盘到磁盘的解决方案:

添加一个包含实际 Assembly 的单独字段,只需订阅 AppDomain.CurrentDomain.AssemblyResolve 并检查是否请求了动态程序集。

如果是,您只需返回您的字段,它就可以正常工作。

例子:

class Program
{
    static Assembly ass;
    public static void Main(string[] args)
    {
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.Run);

        var moduleBuilder = assembly.DefineDynamicModule("Test");

        var baseTypeBuilder = moduleBuilder.DefineType("Base", TypeAttributes.Public, typeof(Object));

        var derivedTypeBuilder = moduleBuilder.DefineType("Derived", TypeAttributes.Public);

        derivedTypeBuilder.SetParent(baseTypeBuilder);

        baseTypeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(XmlIncludeAttribute).GetConstructor(new[] { typeof(Type) }), new[] { derivedTypeBuilder }));

        var baseType = baseTypeBuilder.CreateType();

        var derivedType = derivedTypeBuilder.CreateType();
        ass = baseType.Assembly;

        var attribute = baseType.GetCustomAttribute<XmlIncludeAttribute>();

        Console.WriteLine(attribute.Type.FullName);
    }

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        return ass;
    }
}

关于c# - 如何将 XmlIncludeAttribute 应用于 TypeBuilder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51648662/

相关文章:

c# - 可能使用yield作为上下文关键字会引起问题

c#在for循环中更改控件的名称

c# - 带有接口(interface)的 Entity Framework 代码优先迁移

c# - 二进制序列化,IFormatter : use a new one each time or store one in a field?

.net - mscorlib.dll 中出现类型为 System.StackOverflowException 的未处理异常

java - 从类型为 "Class<?>"的对象启动 main 方法

javascript - 路由时 ASP.NET 设计恶化

.net - 清除 Windows 窗体中的 DrawRectangle

php - JavaScript 中的动态对象初始化(就像 PHP 反射允许的那样)?

java - 如何从名称中获取任意枚举的实例作为字符串