【问题标题】:Reflection.Emit Building a entity graphReflection.Emit 构建实体图
【发布时间】:2013-11-12 14:38:28
【问题描述】:

我花了一些时间尝试使用 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
}

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

【问题讨论】:

  • 如果您显示一些发出代码以及您遇到问题的地方可能会有所帮助。
  • 如果您有设计时定义,您是否考虑过使用 Activator.CreateInstance,如果您只有运行时定义,您是否考虑过使用 dynamic 关键字或 ExpandoObject?
  • 您是否考虑过使用 Roslyn 或类似方法的更高级别的方法? Reflection.Emit 往往很难做到正确。
  • svick,是的,Reflection.Emit 确实有点难以正确。我看着 Roslyn,它看起来很有趣,我成功地构建了我的类型,我肯定会投入更多的时间来研究 Roslyn。谢谢你为我指明了那个方向。不过,对于这个项目,我不能使用 Roslyn,因为它仍然是 CTP,我不允许在生产环境中使用它。现在在我的项目中,我将选择下面发布的解决方案 kkokosa。感谢您花时间回答我的问题!

标签: c# reflection.emit


【解决方案1】:

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

    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);
    }

【讨论】:

  • 感谢您的回答,我将在我的项目中使用此解决方案,它很简单,可以满足我的需求。出于某种原因,我忽略了使用 CodeDom 的可能性,认为 Reflection.Emit 是要走的路。谢谢你启发我。我将使用它在运行时使用来自使用实体框架 poco 的提供者的元数据创建 DTO 对象。
猜你喜欢
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2011-01-19
  • 2011-04-08
  • 1970-01-01
  • 2011-08-19
  • 1970-01-01
相关资源
最近更新 更多