用户代码序列化:CodeDom的力量
VS.NET中的主要对象持续性机制是通过直接的代码发送来处理的。在所有Web和Windows Forms包含的InitializeComponent方法中,你已经看到了这一现象。在Component-继承类型中也显示了这一过程。两个属性决定了这一行为:System.ComponentModel.Design.Serialization.RootDesignerSerializerAttribute以及System.ComponentModel.Design.Serialization.DesignerSerializerAttribute.,正如在开始讨论到的DesignerAttribute,在根和标准串化器之间有一个明显的区别。但是不像DesignerAttribute,总是利用标准(非-根)串化器,当构件同时是被设计的根构件时,要额外利用根串化器。通常只是定制非-根串化器。此非-根串化器的指示器就是:IComponent接口已经包含根串化器。
[RootDesignerSerializer(typeof(RootCodeDomSerializer), typeof(CodeDomSerializer))]但是它没有提供设计常规串化器的属性。但是,IComponent的特殊实现提供这个属性。例如:
public interface IComponent
[DesignerSerializer(typeof(Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer)),以及
typeof(CodeDomSerializer))]
public class System.Web.UI.Control : IComponent
[DesignerSerializer(typeof(System.Windows.Forms.Design.ControlCodeDomSerializer)),注意:两者都有它们独特的串化器,因为Windows窗体被保存到代码的方法与Web 窗体被保存到代码的方法有很大的区别。前者串行化InitializeComponent方法的所有值和设置,然而后者仅仅储存在代码隐藏事件处理程序连接附件中,因为控件属性被保存在aspx页面中。
typeof(CodeDomSerializer))]
public class System.Windows.Forms.Control : Component
你肯定注意到不管控件是用在VB.NET项目中还是用在一个C#项目(或者是可用于此目的的其它语言)中,InitializeComponent总是用正确的语言发送代码。因为.NET中一个新的功能(此功能被称为CodeDom. )CodeDom是一个类型集,此类型集允许我们输写对象层次结构 ,这些对象层次结构代表更加的普通语言构造,例如:类型,领域以及属性宣告,事件连接附件,try..catch..finally块等等。它们允许我们创建一个所谓的预期目标代码的abstract syntax tree (AST)。abstract syntax tree (AST)是抽象的,它不代表VB.NET或者C#代码,但是代表constructs它们自己。
串化器传递到集成开发环境的东西就是包含代码的ASTs,这正是它们期望保存的。集成开发环境依次创建一个System.CodeDom.Compiler.CodeDomProvider -继承类型,System.CodeDom.Compiler.CodeDomProvider -继承类型与当前项目完全匹配,例如:Microsoft.CSharp.CSharpCodeProvider 或者Microsoft.VisualBasic.VBCodeProvider.此对象最后负责以具体语言代码传输AST,而这些具体语言代码早已被嵌入到了InitializeComponent方法中。
CodeDom并不是非常复杂,让我们来迅速地学习一下CodeDom。