Visual Studio 核心代码模型(Addin+CodeModel)使用心得
2011-01-09 11:15
531 查看
我们知道Visual Studio 2010的UML设计功能已经可以做到正向工程了,但是这些生成的代码都是空架子,还得经过手工处理填充上业务逻辑代码,如果系统是基于某个具体技术框架进行开发的话,还必须加上这些技术框架的特性代码。比如:
代码里面的[Serializable]、[EnumCaption("否")]都是需要附加到代码里的。
为了实现快速开发,减少开发工作量,这些工作是否可以让机器代劳?利用“Visual Studio 自动化对象模型”技术似乎是个可行方案。
http://msdn.microsoft.com/zh-cn/library/za2b25t3(v=VS.80).aspx
只要我们在VS的IDE里利用Addin插件技术,参与到它的代码编辑功能中,通过分析类的定义,将技术框架的特征码嵌入到代码文本中。
基于上述的想法,我们开始探索之旅:
1,在代码编辑窗体的弹出菜单里嵌入一个菜单项,借此触发实现我们的需求:
基于网上有很多编写Connect类的介绍,本文不再多说,代码节选如下:
2,通过当前活动的编辑窗体ActiveDocument找到它的工程项ProjectItem,通过工程项得到我们需要的FileCodeModel:
FileCodeModel2 codeModel = (FileCodeModel2)_applicationObject.ActiveDocument.ProjectItem.FileCodeModel;
我们知道FileCodeModel是操作代码模型的入口:
http://msdn.microsoft.com/zh-cn/library/envdte.filecodemodel.aspx
3,通过FileCodeModel,我们可以对当前代码编辑框内的代码进行改写了,但是首先要找到改写的点,由于FileCodeModel是一个树,我们要遍历它,为了方便遍历,写了这样的公共函数:
我们要找到这个代码文本中所有的枚举定义,应该这么做:
CodeModelHelper.FindAllCodeElement(codeModel.CodeElements, vsCMElement.vsCMElementEnum)
返回的是符合vsCMElement.vsCMElementEnum条件的CodeElement的集合,我们遍历这个集合,可以将把[Serializable]添加到枚举上:
结论:
上述简单地演示了一个通过Addin插件来有针对性地批量修改代码的方法,在此基础上,我们可以做很多有趣的事情,但是目的是一个,就是尽可能偷懒,即加快我们开发又不出错。
/// <summary> /// 布尔值选项 /// </summary> [Serializable] public enum BooleanOption { /// <summary> /// 否 /// </summary> [EnumCaption("否")] N, /// <summary> /// 是 /// </summary> [EnumCaption("是")] Y }
代码里面的[Serializable]、[EnumCaption("否")]都是需要附加到代码里的。
为了实现快速开发,减少开发工作量,这些工作是否可以让机器代劳?利用“Visual Studio 自动化对象模型”技术似乎是个可行方案。
http://msdn.microsoft.com/zh-cn/library/za2b25t3(v=VS.80).aspx
只要我们在VS的IDE里利用Addin插件技术,参与到它的代码编辑功能中,通过分析类的定义,将技术框架的特征码嵌入到代码文本中。
基于上述的想法,我们开始探索之旅:
1,在代码编辑窗体的弹出菜单里嵌入一个菜单项,借此触发实现我们的需求:
基于网上有很多编写Connect类的介绍,本文不再多说,代码节选如下:
/// <summary>实现 IDTExtensibility2 接口的 OnConnection 方法。接收正在加载外接程序的通知。</summary> /// <param term='application'>宿主应用程序的根对象。</param> /// <param term='connectMode'>描述外接程序的加载方式。</param> /// <param term='addInInst'>表示此外接程序的对象。</param> /// <seealso class='IDTExtensibility2' /> public void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom) { _applicationObject = (DTE2)Application; _addInInstance = (AddIn)AddInInst; //如果是安装状态或是插件刚被启动的状态,则创建菜单 if (ConnectMode == Extensibility.ext_ConnectMode.ext_cm_UISetup || ConnectMode == Extensibility.ext_ConnectMode.ext_cm_Startup) { //取代码编辑窗口右键弹出菜单的工具条 CommandBar codeWindowBar = ((CommandBars)_applicationObject.CommandBars)["Code Window"]; //将菜单项加入工具条 object[] contextGUIDS = new object[] { }; Command commandObj = _applicationObject.Commands.AddNamedCommand(_addInInstance, _buildClassMenuName, "构建业务类/规则类", "业务类由指定的数据库表/视图映射", true, 137, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled ); commandObj.AddControl(codeWindowBar); } }
2,通过当前活动的编辑窗体ActiveDocument找到它的工程项ProjectItem,通过工程项得到我们需要的FileCodeModel:
FileCodeModel2 codeModel = (FileCodeModel2)_applicationObject.ActiveDocument.ProjectItem.FileCodeModel;
我们知道FileCodeModel是操作代码模型的入口:
http://msdn.microsoft.com/zh-cn/library/envdte.filecodemodel.aspx
3,通过FileCodeModel,我们可以对当前代码编辑框内的代码进行改写了,但是首先要找到改写的点,由于FileCodeModel是一个树,我们要遍历它,为了方便遍历,写了这样的公共函数:
internal static class CodeModelHelper { public static List<CodeElement2> FindAllCodeElement(CodeElements elements, vsCMElement kind) { List<CodeElement2> result = new List<CodeElement2>(); FindAllCodeElement(elements, kind, ref result); return result; } private static void FindAllCodeElement(CodeElements elements, vsCMElement kind, ref List<CodeElement2> elementList) { if (elements != null) foreach (CodeElement2 item in elements) { if (item.Kind == kind) elementList.Add(item); FindAllCodeElement(item.Children, kind, ref elementList); } } }
我们要找到这个代码文本中所有的枚举定义,应该这么做:
CodeModelHelper.FindAllCodeElement(codeModel.CodeElements, vsCMElement.vsCMElementEnum)
返回的是符合vsCMElement.vsCMElementEnum条件的CodeElement的集合,我们遍历这个集合,可以将把[Serializable]添加到枚举上:
public void Exec(string CmdName, vsCommandExecOption ExecuteOption, ref object VariantIn, ref object VariantOut, ref bool Handled) { if (ExecuteOption == vsCommandExecOption.vsCommandExecOptionDoDefault) { if (CmdName == _buildClassCmdName) { FileCodeModel2 codeModel = (FileCodeModel2)_applicationObject.ActiveDocument.ProjectItem.FileCodeModel; ExecuteBuildEnumClass(CodeModelHelper.FindAllCodeElement(codeModel.CodeElements, vsCMElement.vsCMElementEnum)); Handled = true; return; } } Handled = false; } private static void ExecuteBuildEnumClass(List<CodeElement2> elementList) { foreach (CodeEnum item in elementList) { item.AddAttribute(typeof(SerializableAttribute).Name, null); } }
结论:
上述简单地演示了一个通过Addin插件来有针对性地批量修改代码的方法,在此基础上,我们可以做很多有趣的事情,但是目的是一个,就是尽可能偷懒,即加快我们开发又不出错。
相关文章推荐
- Visual Studio 核心代码模型(Addin+CodeModel)使用心得 .
- visual studio code and unity||mac 下使用visual studio 调试unity代码
- Unity3d使用心得(1):ModelImporter的使用、在代码中添加动画片段。
- (转)Unity3d使用心得(1):ModelImporter的使用、在代码中添加动画片段。
- visual studio code and unity||mac 下使用visual studio 调试unity代码
- Unity3D使用心得(1):ModelImporter的使用、在代码中添加动画片段。
- Unity3D使用心得(1):ModelImporter的使用、在代码中添加动画片段。
- Unity3d使用心得(1):ModelImporter的使用、在代码中添加动画片段。
- ecmall中static变量的使用-model模型代码设计
- 说说标准——CSS核心可视化格式模型(visual formatting model)之九:浮动(Float)定位细则二
- (三)使用预定义模型QDirModel的例子
- 美化Visual Studio代码编辑器的字体,使中文和英文使用不同的字体
- 使用ASP.NET中关于代码分离的心得体会(转)
- linear_model:线性模型使用
- 使用 SharePoint 对象模型时的常见代码问题 (来源MSDN)
- 免费的VC可重用代码管理器插件(CodeManagerAddIn)
- iOS使用核心的50行代码实现一个路由组件
- 说说标准——CSS核心可视化格式模型(visual formatting model)之十:控制紧接浮动的排列-clear 特性
- 在 Visual Studio 或 SQLServer Management Studio 的代码编辑器中使用正则表达式匹配日期格式
- 使用Visual Studio(VS)开发Qt程序代码提示功能的实现