首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将XmlIncludeAttribute应用于TypeBuilder?

如何将XmlIncludeAttribute应用于TypeBuilder?
EN

Stack Overflow用户
提问于 2018-08-02 08:09:55
回答 3查看 290关注 0票数 12

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

代码语言:javascript
复制
[XmlInclude(typeof(Derived))]
public class Base
{
}

public class Derived : Base
{
}

我使用TypeBuilder类的方式如下:

代码语言:javascript
复制
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>();
    }
}

呼吁:

代码语言:javascript
复制
var attribute = baseType.GetCustomAttribute<XmlIncludeAttribute>();

我收到以下错误:

无法加载文件或程序集“测试、Version=0.0.0.0、Culture=neutral、PublicKeyToken=null”或其依赖项之一。系统找不到指定的文件.

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

P.S:我使用的是VisualStudio2017 (v15.7.5)和C#类库(.NET框架项目模板)、而不是.NET Core或.NET标准

EN

回答 3

Stack Overflow用户

发布于 2018-09-20 14:19:18

无法提供更多的理由,而只能提供一种无需额外加载/卸载或任何进出磁盘即可工作的解决方案:

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

如果是的话,你只需要返回你的领域,它的工作非常好。

示例:

代码语言:javascript
复制
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;
    }
}
票数 7
EN

Stack Overflow用户

发布于 2018-09-20 14:11:23

我复制了你的例外。看起来,.NET框架希望从磁盘中读取一个模块。

因此,最简单的解决方法是将程序集保存到磁盘:

代码语言:javascript
复制
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
  new AssemblyName("Test"), 
  AssemblyBuilderAccess.RunAndSave); // allow run & save

var moduleBuilder = assembly.DefineDynamicModule("Test",
  "Test.dll"); // specify a file name where module will be stored

...

var baseType = baseTypeBuilder.CreateType();
var derivedType = derivedTypeBuilder.CreateType();

assembly.Save("Test.dll");

现在,我可以毫无例外地获得属性:

代码语言:javascript
复制
var attribute = baseType.GetCustomAttribute<XmlIncludeAttribute>();
票数 4
EN

Stack Overflow用户

发布于 2018-09-21 10:29:29

好吧,我可以告诉你为什么fix @X39会起作用。跨出baseType.GetCustomAttribute()的框架代码林(可能是不同区域性的退步);当最终到达appdomain.cs时,我看到:

此时,_AssemblyResolve是null (这是AppDomain.CurrentDomain.AssemblyResolve的私有备份字段),在逐步返回null之后,代码会与您发布的错误一起崩溃。

更多信息:https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.assemblyresolve?view=netframework-4.7.2

@X39请随意合并我的答案,让我知道,这样我就可以删除我的答案,我不想直接编辑你的答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51648662

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档