上一章主要讲了这个插件的操作界面与功能,这一章我们开始讲解如何实现该插件。
创建Add-In项目
打开VS,创建新项目->选择其它项目类型->Visual Studio外接程序。如下图:
确定,下一步直到完成,注意在第四页的时候修改一下默认值,如下图:
在项目创建完成后,VS将会自动生成一个Connect.cs文件。该文件包含很多个方法,分别为插件在不同生命周期将会触发的方法。这里我们只需要关注Exec方法就可以了,这个方法是我们在调用该插件时将会执行的方法。在这个文件,我们还需要大概了解一下DTE2接口,因为我们需要将自动生成的_
ApplicationObject对象赋予一会我们将要创建的WinForm窗体。DTE2接口在MSDN中的解释是: Visual Studio 自动化对象模型中的顶级对象,它继承自DTE接口,而DTE对象表示Visual Studio 集成开发环境(IDE),这里我们就理解为它就是我们的IDE环境了。
源码讲解
接着我们在项目中新建一个WinForm窗体TableConfig。因为在该窗体中需要对宿主项目进行操作,所以我们必须创建一个DTE2对象,并在Connect.cs文件中将_ApplicationObject对象赋给它。代码如下:
public partial class TableConfig : Form
{
public TableConfig()
{
InitializeComponent();
}
public DTE2 DTEObject
{
get;
set;
}
}
然后改写Connect.cs中的Exec方法如下:
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if (commandName == "CreateCode.Connect.CreateCode")
{
TableConfig form = new TableConfig();
form.DTEObject = _ApplicationObject;
form.ShowDialog();
handled = true;
return;
}
}
}
按照上一章的界面介绍,将所需的控件拖到WinForm窗体中。WinForm窗体的cs文件代码大家可以在源码中查看,没有什么特别的地方。这里就不讲了。
最终的源文件如下图所示,我们一一讲解一下。
一、Common.cs的源码如下:
//获取表或视图的列结构
public DataTable GetTableFrame(string tablename)
{
string sql = @"select row_number() over(order by column_id asc) as ID,A.is_computed as iscomputed,A.is_identity as isidentity,
A.name as columnname,B.name columntype,A.max_length as columnlength
from
sys.columns A
left join sys.types B on A.system_type_id=B.system_type_id
where object_id=object_id('" + tablename + "')";
return dbhelpsql.GetData(sql);
}
//获取表的主键信息
public DataTable GetTableKeys(string tablename)
{
string sql = @"select o.name as tablename,c.name as columnname,d.name as columntype,c.max_length as columnlength
from
sys.indexes i
join sys.sysindexkeys k on i.object_id = k.id and i.index_id = k.indid
join sys.objects o on i.object_id = o.object_id
join sys.columns c on i.object_id=c.object_id and k.colid = c.column_id
join sys.types d on c.system_type_id=d.system_type_id
where o.type='u'
and exists(select 1 from sysobjects where xtype = 'PK' and name =i.name)
and o.name='" + tablename + "'order by k.colid asc";
return dbhelpsql.GetData(sql);
}
这两个方法主要是用来获取指表的结构信息,如果有看不懂的地方,请考参sql目录视图来理解。
二、CreateFile.cs的源码如下:
public class CreateFile
{
//代表整合式开发环境 (IDE) 中所有的项目和适用整个方案的属性
Solution3 solu;
public CreateFile(Solution3 _solu)
{
this.solu = _solu;
}
public void CreateItem(string ItemName, string Folder, string fileName)
{
//取得方案中目前项目的集合
Projects projects = solu.Projects;
foreach (Project pi in projects)
{
if (pi.Name == ItemName)
{
//ProjectItem 表示项目中的项
foreach (ProjectItem p in pi.ProjectItems)
{
if (p.Name == Folder)
{
//GetProjectItemTemplate 传回指定项目项目范本的路径(范本名称,用以撰写范本的语言)
//这里的Class.zip与CSharp是vs自带的class类项目模板
string templatePath = solu.GetProjectItemTemplate("Class.zip", "CSharp");
//AddFromTemplate(FileName,Name) 在现有项模板文件中创建一个新项目项并将其添加到项目中(模板项目文件的完整路径和文件名,新项目项的文件名)
p.ProjectItems.AddFromTemplate(templatePath, fileName + ".cs");
break;
}
}
}
}
}
}
CreateItem方法功能,就是先在解决方案中,找到指定的项目,然后在找到的项目中,找到指定的文件夹,然后在找到的文件夹中,创建指定的文件。如果有一项没有满足,则不创建任何文件。基本上每段代码上面我都有增加了注释,所以应该不难理解。如果有对”项目范本”这个概念不太明白的同学,可以到百度中搜索一下。我们在vs项目中添加的每个文件都会有一个对应的模板文件。我们也可以自己创建与添加模板文件。
三、DataType.cs文件主要就是sqlserver与C#变量类型的对应,因为在生成DAL层数据的时候,这两者之间是需要转换的。
四、DbHelperSQL.cs, MyMessageBox.cs,TableFrame.cs, tools.cs是辅助类,没什么特别的地方。
余下三个文件源码比较长,放在下一章。