在运行时编写和更改代码

时间:2013-10-15 06:01:12

标签: c# code-generation reflection.emit codedom roslyn

我有一种情况,我想在运行时使用他们的EditorFor / DisplayFor模板(或类似的东西)构建MVC样式视图。

理想情况下,我们的应用程序会让用户在他们的UI中选择他们想要的字段(因此他们可以根据需要添加/删除任何字段),为此我认为在运行时创建viewmodel classess很方便。根据用户选择的内容(即stringlength,required等)将各种dataannotation属性添加到它们中。

我需要支持的一件事是在运行时更改生成的类,而不会影响其他用户或不必执行完整的iisreset。

为此,我一直在做一些研究,看起来可能有3种不同的方法,CodeDom,RunSharp / Relfection.Emit,Roslyn。

从我可以告诉反射.Emit / Runsharp将允许我创建类并在运行时向它们添加属性和属性,并且可能在我需要时修改它们而没有不利影响。

我不确定Roslyn是否允许这样做,我无法找到创建具有属性或属性的类的任何简单示例,并且我已经看到一些提及Roslyn的输出是不可变的所以我不确定如何允许我在以后修改它而不会产生不利影响。

总的来说,从我看到的情况来看,大多数人都不推荐使用CodeDom,因此我不能完全确定是否应该打扰这条路线。

任何人都可以告诉我这些方向对我来说可行吗?

1 个答案:

答案 0 :(得分:1)

所以,这些解决方案都不会起作用,老实说,在运行时生成类型真的不是你想要的。

说到CLR,一旦你有一个包含字段和方法的类型,你就无法在运行时真正添加新成员或更改成员。我们最接近的是Visual Studio中的编辑和继续功能,我们高度限制我们可以做出哪些更改。我们经常通过不添加您认为添加的方法或属性来“欺骗”,但我们将它们隐藏在其他位置并在您进行编辑时发出引用此秘密位置的IL。删除成员等疯狂的东西完全不受支持。即使支持 ,许多代码也喜欢假设执行someObject.GetType().GetMembers()一遍又一遍地返回相同的内容。

就Roslyn而言,当我们说结果是“不可变的”时,我们并不意味着对任何可能产生IL的IL提出任何要求。相反,当您要求Roslyn解析某些内容或分析源代码时,对象(语法树,类型信息等)是不可变的。但是,这并不重要,因为一旦它们存在就无法修改CLR中的类型。

我对他的评论感到厌恶 - 这不是你想要做的。使用一些适当的数据结构在运行时表示您的信息,而不是试图将其视为可以某种方式进行变异的具体类。