前言 说真的,前面几篇随笔读起来会很乏味,写起来更是如此。不过好戏总在后头,从这一篇开始我将介绍在Add-In中对VS的各个元素进行操作,这些会有意思得多。 大多数时候,我们在VS中进行开发,都是从打开解决方案开始,然后找到项目、打开文件进行开发。本文将介绍与此相关的内容。 解决方案、项目和项简介 我相信,这三者对我们.NET开发人员来说是再熟悉不过的了。但它们在AOM(自动化对象模型)的表示方式跟我们想象的会不太一样。看下面的图1,其中涉及的主要元素有解决方案、解决方案文件夹、项目、文件夹、文件。AOM通过Solution接口表示解决方案;Project接口表示解决方案文件夹和项目;ProjectItem接口表示文件夹和文件。下面我会通过一个例子来介绍它们。 简单的代码生成器 在实际开发中,我们往往需要采用一些特定的技术方案,这些方案就决定了程序的整体架构,表现在程序中就是一些项目、程序集、配置文件的组织。曾经有段时间很喜欢iBATIS.NET,这里就以它的示例项目NPetshop为例进行演示。NPetshop的基本结构如下: |
图1:NPetshop的程序结构 它的代码可以在NPetshop Source for .NET 2.0一文中找到。External-bin里面是所需要的各个程序集,Domain是实体类,Persistence是数据访问层,Service是业务逻辑层,Presentation是表现逻辑层,Web则负责最终的表现。如果要采用这样的解决方案进行开发,那么在项目开始我们就得花些时间来搭建整个解决方案的框架。通过Add-In,我们可以做到“一次编写,多次使用”。 现在来看看如何从零开始创建一个解决方案。在本例中,大致过程是: |
图2:解决方案创建过程 下面就来一步步实现。 0)添加命令 在之前的随笔已经向NEnhancer添加了两个命令了,现在需要添加新的命令,这样重复代码又得多一些了,所以在添加命令之前,先将代码重构一下,提取出几个小方法: C# Code - Connect类的辅助方法
C# Code - 添加命令
唯一需要用户输入的信息是解决方案的名称(这里假定各项目的名称都以此为前缀)和目录,这需要创建一个简单的窗体(NPetshopSlnGenerator)来收集信息。 |
图3:Generator窗体 在AOM中,表示解决方案的类型是EnvDTE.Solution(以及其后续版本Solution2、Solution3),它的重要方法和属性有:
Solution的完整成员列表请参看MSDN。要访问VS中的当前解决方案,可使用DTE.Solution属性,下面是创建解决方案的代码: C# Code - 创建解决方案
Solution3 sln = (DTEObject.Solution as Solution3); sln.Create(currentSlnPath, slnName);
2)创建解决方案文件夹 在这一步,首先要把所需的程序集等文件拷贝到新解决方案所在目录,然后创建解决方案文件夹,将文件添加进去: C# Code - 创建SolutionFolder
Project sfProj = sln.AddSolutionFolder(ExternalBinDirectoryName); foreach (string file in Directory.GetFiles(ExternalBinPath)) { sfProj.ProjectItems.AddFromFile(file); }
3)创建各个项目 由于项目之间会有依赖关系,所以考虑按依赖关系进行创建,也就是Domain->Persistence->Service->Presentation->Web。 表示项目的类型为EnvDTE.Project,它的主要方法和属性有:
Project的完整成员列表请参看MSDN。创建Domain项目的代码大致如下: C# Code - 创建项目
string classLibProjTemplatePath = sln.GetProjectTemplate("ClassLibrary.zip", "CSharp"); string domainProjName = slnName + "." + "Domain"; sln.AddFromTemplate(classLibProjTemplatePath, Path.Combine(currentSlnPath, domainProjName), domainProjName, false); Project domainProj = GetProjectByName(sln, domainProjName); VSProject vsDomainProj = domainProj.Object as VSProject; vsDomainProj.References.Add(Path.Combine(ExternalBinPath, "IBatisNet.Common.dll"));
接下来是Persistence项目,过程与Domain基本相同,但是要给它添加对Domain项目的引用,此时应使用References.AddProject方法: C# Code - 添加项目引用
vsPersistProj.References.AddProject(domainProj);
4)创建文件夹和文件 在AOM中,文件夹和文件统一表示为ProjectItem类型。它的主要方法和属性为:
ProjectItem的完整成员列表请参看MSDN。Project接口有一个ProjectItems集合属性,可以访问项目所包含的项,同时该属性还可用来添加新的项。在本例中,要添加几个文件夹和文件: C# Code - 添加文件夹和已有文件
webProj.ProjectItems.AddFolder("Maps", Constants.vsProjectItemKindPhysicalFolder); webProj.ProjectItems.AddFromFileCopy( Path.Combine(GetAddinPath(), @"ibatis-config\dao.config"));
C# Code - 根据模板添加文件
string templatePath = sln.GetProjectItemTemplate("Interface.zip", "CSharp"); webProj.ProjectItems.AddFromTemplate(templatePath, "MyInterface.cs");
文中示例的代码可以从这里下载。 我们身在何处? 在VS中,解决方案、项目和文件(夹)是其基本组织形式,也是我们开发人员最为熟悉的元素了,本文介绍的就是与此相关的基本操作。这些操作是通过开发一个具备初步功能的代码生成器来演示的,其中可以了解如何从解决方案开始,自上而下逐步生成项目、文件夹和文件。但是需要说明的是,这里没有对Solution Explorer的操作,也没有涉及到对文件内容的操作,这些都将在后续的随笔中介绍。 |