C# 反射。生成实体图

C# 反射。生成实体图,c#,reflection.emit,C#,Reflection.emit,我花了一些时间尝试使用Reflection.Emit动态构建实体图。使用新的平面类型(类)创建程序集,实例化它并将其与反射一起使用是很容易的,而且效果很好。但当涉及到用另一个动态类的泛型列表构建结构时,它变得更加复杂,我陷入了困境。基本上,我希望动态构建以下结构: public class Head { public string HeadId { get; set; } public AssignmentType HeadType { get; set; } publi

我花了一些时间尝试使用Reflection.Emit动态构建实体图。使用新的平面类型(类)创建程序集,实例化它并将其与反射一起使用是很容易的,而且效果很好。但当涉及到用另一个动态类的泛型列表构建结构时,它变得更加复杂,我陷入了困境。基本上,我希望动态构建以下结构:

public class Head
{
    public string HeadId { get; set; }
    public AssignmentType HeadType { get; set; }
    public int TestIndicator { get; set; }
    public List<Item> Items { get; set; }

    public Head()
    {
        Items = new List<Item>();
    }
}

public class Item
{
    public string ItemId { get; set; }
    public int Weight { get; set; }
    public List<Description> Descriptions { get; set; }

    public Item()
    {
        Descriptions = new List<Description>();
    }
}

public class Description
{
    public string DescriptionText { get; set; }
    public string Country { get; set; }
}

public enum AssignmentType
{
    TypeA,
    TypeB,
    TypeC
}
公共类负责人
{
公共字符串头ID{get;set;}
公共AssignmentType头类型{get;set;}
公共int测试指示符{get;set;}
公共列表项{get;set;}
公共主管()
{
项目=新列表();
}
}
公共类项目
{
公共字符串ItemId{get;set;}
公共整数权重{get;set;}
公共列表描述{get;set;}
公共项目()
{
描述=新列表();
}
}
公共类描述
{
公共字符串DescriptionText{get;set;}
公共字符串国家{get;set;}
}
公共枚举分配类型
{
TypeA,
B型,
C型
}

我一直在寻找大量的例子,但到目前为止,我还没有找到任何解决这个问题的方法。如果有人有一个示例,或者可以为我指出使用Reflection.Emit解决此问题的正确方向,我将不胜感激。

最简单的解决方案是使用
CSharpCodeProvider
from
Microsoft.CSharp
命名空间:

    string source = "public class Description" +
                    "{" +
                    "   public string DescriptionText { get; set; }" +
                    "   public string Country { get; set; }" +
                    "}";

    CSharpCodeProvider codeProvider = new CSharpCodeProvider();
    System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
    parameters.GenerateExecutable = false;
    parameters.GenerateInMemory = true;
    CompilerResults result = codeProvider.CompileAssemblyFromSource(parameters, source);
    if (!result.Errors.HasErrors)
    {
        Type type = result.CompiledAssembly.GetType("Description");
        var instance = Activator.CreateInstance(type);
    }

最简单的解决方案是使用
CSharpCodeProvider
来自
Microsoft.CSharp
命名空间:

    string source = "public class Description" +
                    "{" +
                    "   public string DescriptionText { get; set; }" +
                    "   public string Country { get; set; }" +
                    "}";

    CSharpCodeProvider codeProvider = new CSharpCodeProvider();
    System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
    parameters.GenerateExecutable = false;
    parameters.GenerateInMemory = true;
    CompilerResults result = codeProvider.CompileAssemblyFromSource(parameters, source);
    if (!result.Errors.HasErrors)
    {
        Type type = result.CompiledAssembly.GetType("Description");
        var instance = Activator.CreateInstance(type);
    }

如果您显示一些emit代码以及遇到问题的地方,这可能会有所帮助。如果您有设计时定义或dynamic关键字,您是否考虑过使用Activator.CreateInstance;如果您只有运行时定义,您是否考虑过使用Roslyn等更高级别的方法?反射。发射往往很难正确。斯维克,是的,反射。发射确实有点难正确。我看了Roslyn,它看起来很有趣,我成功地构建了我的类型,我肯定会投入更多的时间调查Roslyn。谢谢你给我指明了那个方向。但是对于这个项目,我不能使用Roslyn,因为它仍然是一个CTP,我不允许在生产环境中使用它。在我现在的项目中,我将使用下面发布的kkokosa解决方案。谢谢你花时间回答我的问题!如果您显示一些emit代码以及遇到问题的地方,这可能会有所帮助。如果您有设计时定义或dynamic关键字,您是否考虑过使用Activator.CreateInstance;如果您只有运行时定义,您是否考虑过使用Roslyn等更高级别的方法?反射。发射往往很难正确。斯维克,是的,反射。发射确实有点难正确。我看了Roslyn,它看起来很有趣,我成功地构建了我的类型,我肯定会投入更多的时间调查Roslyn。谢谢你给我指明了那个方向。但是对于这个项目,我不能使用Roslyn,因为它仍然是一个CTP,我不允许在生产环境中使用它。在我现在的项目中,我将使用下面发布的kkokosa解决方案。谢谢你花时间回答我的问题!谢谢你的回答,我会在我的项目中使用这个解决方案,它很简单,并且做我需要的事情。出于某种原因,我忽略了使用CodeDom的可能性,认为Reflection.Emit是一种方法。谢谢你启发我。我将使用它在运行时使用来自使用实体框架poco的提供者的元数据创建DTO对象。谢谢你的回答,我将在我的项目中使用这个解决方案,它很简单,可以满足我的需要。出于某种原因,我忽略了使用CodeDom的可能性,认为Reflection.Emit是一种方法。谢谢你启发我。我将使用它在运行时使用来自使用实体框架poco的提供者的元数据创建DTO对象。