收藏一款好用的基于.NET的配置文件设计工具
2011-09-16 13:17
543 查看
在进行框架开发的过程中,我们往往需要对配置文件的结构进行设计,以便产生一套完整的配置方案,供开发人员在使用框架时能对框架进行配置。对于某些大型的框架,其配置节点的结构可能相当复杂,比如某个配置节点(Configuration Element)可以有属性,还可以在其下挂载多个其它的配置节点或者多个配置节点集合(Configuration Element Collection)。如果使用手动编写代码的方式来维护与配置相关的代码,势必会出现大量的重复劳动,比如,需要给每个配置属性添加System.Configuration.ConfigurationPropertyAttribute特性,需要为各个配置节点集合采用相同的代码编写模式(例如重写其中的CreateElement等方法)。这样做不仅耗时而且容易出错。更进一步,Visual
Studio支持智能感知技术,如果我们在配置文件编辑器上设置了所要用到的配置信息XSD Schema文件,我们就可以利用智能感知方便快速地编写配置文件。然而,如果我们的配置节点采用手工代码维护,那么在编写完代码之后,还需要另外编写一套XSD Schema文件,以使得开发人员在使用我们的框架时,能够享受到智能感知带来的便捷,这样做不仅工作量大,而且一旦配置信息结构变得复杂,我们就很难确保代码与XSD Schema之间的对应关系。
今天我向大家介绍一款个人觉得比较不错的基于.NET的配置文件设计工具:Configuration Section Designer。它是一款使用Microsoft Visualization & Modeling SDK开发的面向配置文件设计领域的领域特定语言(DSL,有关DSL的知识,我会在后续的博客文章中向大家介绍)。如果你使用的是Visual Studio
2005/2008,你可以去Configuration Section Designer的主页下载安装包。如果你使用的是Visual Studio 2010,那么你还可以使用VS2010的Extension Manager来找到这个设计工具。
2010进行介绍。
在得到VSIX扩展包后,双击直接打开运行就可以将其安装到Visual Studio 2010的开发环境中。
在完成Designer Surface的创建之后,我们可以看到在项目中多了一个.csd的文件,在Toolbox中,也出现了与配置文件设计相关的工具:
看上去是不是有点像ADO.NET Entity Framework的设计器?不错,这就是Microsoft Visualization & Modeling SDK给我们带来的强大功能:它允许开发人员设计自己的领域特定语言(Domain Specific Language, DSL),并以VSIX等扩展包的方式集成到Visual Studio开发环境中。
Description,然后使用System.ComponentModel.DataAnnotations.MetadataTypeAttribute特性以在用于描述源类型的元数据类型上进行特性设置。以下是这种实现方式的相关代码:
然而对于Configuration Section Designer而言,这种繁杂的实现方式已经不复存在。它本身就支持Component Model相关特性的设置,然后会在产生的代码中添加相应的特性描述,大大减轻了开发者的负担。
产生的代码如下:
Configuration Section Designer应该还有很多不错的功能,时间关系我也没有进行深入研究,有兴趣的朋友不妨下载一个Configuration Section Designer体验一下。
Studio支持智能感知技术,如果我们在配置文件编辑器上设置了所要用到的配置信息XSD Schema文件,我们就可以利用智能感知方便快速地编写配置文件。然而,如果我们的配置节点采用手工代码维护,那么在编写完代码之后,还需要另外编写一套XSD Schema文件,以使得开发人员在使用我们的框架时,能够享受到智能感知带来的便捷,这样做不仅工作量大,而且一旦配置信息结构变得复杂,我们就很难确保代码与XSD Schema之间的对应关系。
今天我向大家介绍一款个人觉得比较不错的基于.NET的配置文件设计工具:Configuration Section Designer。它是一款使用Microsoft Visualization & Modeling SDK开发的面向配置文件设计领域的领域特定语言(DSL,有关DSL的知识,我会在后续的博客文章中向大家介绍)。如果你使用的是Visual Studio
2005/2008,你可以去Configuration Section Designer的主页下载安装包。如果你使用的是Visual Studio 2010,那么你还可以使用VS2010的Extension Manager来找到这个设计工具。
下载与安装
可以到Configuration Section Designer的下载页面下载并安装该工具。如果你使用的是Visual Studio 2005/2008,你将得到一个EXE的安装程序;如果你使用的是Visual Studio 2010,你将得到一个VSIX的扩展包。我使用的是Visual Studio 2010,因此接下来都会以Visual Studio2010进行介绍。
在得到VSIX扩展包后,双击直接打开运行就可以将其安装到Visual Studio 2010的开发环境中。
新建配置文件项目
首先你可以使用Visual Studio 2010随便创建一个项目(比如Class Library或者Console Application都可以),然后在这个项目上单击鼠标右键,选择Add –> New Item菜单,这将打开Add New Item对话框,在Installed Templates –> Visual C# Items节点下,找到ConfigurationSectionDesigner,更改名称后单击Add按钮。在完成Designer Surface的创建之后,我们可以看到在项目中多了一个.csd的文件,在Toolbox中,也出现了与配置文件设计相关的工具:
看上去是不是有点像ADO.NET Entity Framework的设计器?不错,这就是Microsoft Visualization & Modeling SDK给我们带来的强大功能:它允许开发人员设计自己的领域特定语言(Domain Specific Language, DSL),并以VSIX等扩展包的方式集成到Visual Studio开发环境中。
功能介绍
本文不打算讲解如何使用Configuration Section Designer来设计配置文件,只对其中的一些非常不错的功能进行介绍。自动化代码与文件的生成
对于一款DSL来说,自动化代码生成不算是什么强大的功能,但是这款工具不仅仅会产生代码,而且还会产生与之相关的XSD Schema以及配置文件样本(Sample Configuration File),能让开发者直观地看到最终效果:配置文件样本测试
在设计配置文件的过程中,你可以直接双击产生的.csd.config(比如上面的ConfigurationSectionDesigner1.csd.config)文件,然后在里面进行编辑,来测试你的设计是否正确。注意这个编辑过程是自带有智能感知的:Windows Forms设计器的支持
一个专业的开发框架在向用户提供配置相关的代码以及XSD Schema的同时,还应该为用户提供方便的配置文件编辑器(例如Microsoft Patterns & Practices Enterprise Library通常都会带有面向各种Application Block的配置编辑器)。试想我们将用Windows Forms及其Property Grid控件来设计一款配置文件编辑器,在将配置对象绑定到Property Grid时,Property Grid会通过反射将该对象下所有的属性都显示出来。然而对于配置编辑器而言,我们不仅需要控制配置对象中各个属性的显示方式,而且还需要对这些属性进行一些描述和归类。如果是手工维护框架中的配置代码,这个问题好解决:直接向每个属性手工添加诸如System.ComponentModel.DescriptionAttribute、System.ComponentModel.BrowsableAttribute等特性即可。但如果整个配置代码都是由某工具自动化生成的,那么你就不能直接在生成的代码上就行手工修改,而只能通过System.ComponentModel.DataAnnotations.AssociatedMetadataTypeTypeDescriptionProvider、System.ComponentModel.CustomTypeDescriptor以及System.ComponentModel.PropertyTypeDescriptor类来扩展MetadataTypeDescription,然后使用System.ComponentModel.DataAnnotations.MetadataTypeAttribute特性以在用于描述源类型的元数据类型上进行特性设置。以下是这种实现方式的相关代码:
public class MyAssociatedMetadataTypeTypeDescriptionProvider : AssociatedMetadataTypeTypeDescriptionProvider { publicMyAssociatedMetadataTypeTypeDescriptionProvider(Type type) :base(type) { } publicMyAssociatedMetadataTypeTypeDescriptionProvider(Type type, Type associatedMetadataType) :base(type, associatedMetadataType) { } privateICustomTypeDescriptor Descriptor { get;set; } publicoverride ICustomTypeDescriptor GetTypeDescriptor(Type objectType,object instance) { if(null == this.Descriptor) this.Descriptor =new MyCustomTypeDescriptor(base.GetTypeDescriptor(objectType, instance)); returnthis.Descriptor; } } public class MyCustomTypeDescriptor : CustomTypeDescriptor { publicMyCustomTypeDescriptor(ICustomTypeDescriptor wrappedTypeDescriptor) { this.WrappedTypeDescriptor = wrappedTypeDescriptor; } privateICustomTypeDescriptor WrappedTypeDescriptor { get;set; } publicoverride AttributeCollection GetAttributes() { returnthis.WrappedTypeDescriptor.GetAttributes(); } publicoverride PropertyDescriptorCollection GetProperties() { PropertyDescriptorCollection properties =this.WrappedTypeDescriptor.GetProperties(); List<PropertyDescriptor> list =new List<PropertyDescriptor>(); foreach(PropertyDescriptor descriptor inproperties) list.Add(newMyPropertyDescriptor(descriptor)); returnnew PropertyDescriptorCollection(list.ToArray(),true); } publicoverride PropertyDescriptorCollection GetProperties(Attribute[] attributes) { returnthis.GetProperties(); } } public class MyPropertyDescriptor : PropertyDescriptor { publicMyPropertyDescriptor(PropertyDescriptor wrappedPropertyDescriptor) :base(wrappedPropertyDescriptor) { this.WrappedPropertyDescriptor = wrappedPropertyDescriptor; } privatePropertyDescriptor WrappedPropertyDescriptor { get; set; } publicoverride voidAddValueChanged(objectcomponent, EventHandler handler) { this.WrappedPropertyDescriptor.AddValueChanged(component, handler); } publicoverride boolCanResetValue(objectcomponent) { returnthis.WrappedPropertyDescriptor.CanResetValue(component); } publicoverride Type ComponentType { get { returnthis.WrappedPropertyDescriptor.ComponentType; } } publicoverride boolIsReadOnly { get { returnthis.WrappedPropertyDescriptor.IsReadOnly; } } publicoverride objectGetValue(objectcomponent) { returnthis.WrappedPropertyDescriptor.GetValue(component); } publicoverride Type PropertyType { get { returnthis.WrappedPropertyDescriptor.PropertyType; } } publicoverride voidRemoveValueChanged(objectcomponent, EventHandler handler) { this.WrappedPropertyDescriptor.RemoveValueChanged(component, handler); } publicoverride voidResetValue(objectcomponent) { this.WrappedPropertyDescriptor.ResetValue(component); } publicoverride voidSetValue(objectcomponent, objectvalue) { List<Attribute> attributes =new List<Attribute>(); this.FillAttributes(attributes); foreach(Attribute attribute inattributes) { ValidationAttribute validationAttribute = attributeas ValidationAttribute; if(null == validationAttribute) continue; if(!validationAttribute.IsValid(value)) thrownew ValidationException(validationAttribute.ErrorMessage, validationAttribute, component); } this.WrappedPropertyDescriptor.SetValue(component, value); } publicoverride boolShouldSerializeValue(objectcomponent) { returnthis.WrappedPropertyDescriptor.ShouldSerializeValue(component); } publicoverride boolSupportsChangeEvents { get { returnthis.WrappedPropertyDescriptor.SupportsChangeEvents; } } } // 以下是使用方式: [MetadataType(typeof(ApplicationElementMetadata))] public partial class ApplicationElement { staticApplicationElement() { TypeDescriptor.AddProvider( newMyAssociatedMetadataTypeTypeDescriptionProvider( typeof(ApplicationElement)),typeof(ApplicationElement)); } } public class ApplicationElementMetadata { [Description("Indicates the provider of the Application.")] publicstring Provider { get; set; } }
然而对于Configuration Section Designer而言,这种繁杂的实现方式已经不复存在。它本身就支持Component Model相关特性的设置,然后会在产生的代码中添加相应的特性描述,大大减轻了开发者的负担。
产生的代码如下:
Configuration Section Designer应该还有很多不错的功能,时间关系我也没有进行深入研究,有兴趣的朋友不妨下载一个Configuration Section Designer体验一下。
相关文章推荐
- 介绍一款好用的基于.NET的配置文件设计工具
- .net 配置文件设计工具 Configuration Section Designer
- “基于关键字匹配的文本过滤系统”配置文件的设计和实现(C/C++源码)
- 一只简单的网络爬虫(基于linux C/C++)————配置文件设计及读取
- .Net 自定义配置文件总结【转载收藏】
- 基于XML的配置文件访问接口设计和实现
- 基于XML的配置文件访问接口设计和实现
- .NET 框架设计 - 模式、配置、工具 Demo 搜索
- XConfigGen——这是一个基于nodejs,用于生成不同环境项目配置文件的小工具
- 基于python的接口测试框架设计(二)配置一些参数及文件
- [导入]从架构设计到系统实施——基于.NET 3.0的全新企业应用系列课程(7):设计基于MMC 3.0的管理工具.zip(8.70 MB)
- Linux 网络接口配置文件及相关工具 (v0.1b)(谢谢,先收藏,后期学习下)
- RDIFramework.NET — 基于.NET的快速信息化系统开发框架- 5.4平台日志、异常管理、生成自动升级配置文件模块
- 从架构设计到系统实施-基于.NET 3.0的全新企业应用之开发基于MMC 3.0的管理工具
- RDIFramework.NET — 基于.NET的快速信息化系统开发框架- 5.4平台日志、异常管理、生成自动升级配置文件模块
- .NET 插件系统框架设计(二) 使用对象序列化实现自定义配置文件管理
- 基于XML的配置文件访问接口设计和实现
- [导入]从架构设计到系统实施——基于.NET 3.0的全新企业应用系列课程(7):设计基于MMC 3.0的管理工具.zip(8.70 MB)
- 基于配置文件的工厂设计模式实现,并且做到对象的单例,类似于spring的ioc
- “基于关键字匹配的文本过滤系统”配置文件的设计和实现(C/C++源码)