Visual Studio 设计模式插件/扩展






4.92/5 (178投票s)
一个Visual Studio插件,可以将一些通用的面向对象模式插入到您的项目中,并在线搜索您的选定文本。
*我建议您从codeplex TFS下载最新的代码和二进制文件。
引言
如果您一直使用面向对象的语言进行编程,那么您一定听说过设计模式。关于这个主题的书籍和网站有很多,但在使用Visual Studio时,您必须离开IDE,刷新您对特定软件模式功能的记忆,然后键入或复制其代码。
难道集成一个Visual Studio工具,帮助您选择正确的模式并只需点击几下即可插入代码,不是更方便吗?
这正是这个Visual Studio插件/扩展所做的:它索引了一些通用的面向对象模式,如“四大设计模式”,并将它们呈现给易于搜索的用户界面,并将其代码插入到您的项目中。
它为您提供了进一步自定义模式的参数,并且适用于Visual Studio支持的语言,如C#、VB.NET、C++等,还可以扩展到其他Visual Studio支持的语言,如F#。
此外,这个插件/扩展还提供了一些不相关的功能,例如可以轻松地在线搜索代码、XML、HTML、错误或引用的窗口中选定的文本或项。Visual Studio的Express版本无法使用此插件,但所有高级或社区版本都可以。
背景
我为VS 2008、2010、2012和2013创建了这个Visual Studio插件,并为VS 2015和2017创建了一个扩展(它们不再支持插件),作为Microsoft IDE用户的便利功能(Express版本不支持插件/扩展)。如果您下载二进制文件或代码, there is a lot of code to deal with Visual Studio automation, custom installer actions, and obviously the patterns loading and rendering. It should support Visual Studio 2008, 2010, 2012, 2013, 2015, 2017 on Windows XP or later. To allow for easy expansion and extensibility, I used XML files and the file system's hierarchical to represent the object oriented pattern information as templates. Also, the architecture is based on Managed Extensibility Framework (MEF) to provide for more customization in additional assemblies.
鉴于代码库非常庞大,您可以在codeplex repository中看到,这次我将只关注用法以及向现有模式添加新模式。如果本文引发足够的兴趣,我将推出续篇,介绍如何创建自定义程序集以进行进一步定制、许可等。
使用插件/扩展
如果您急于观看此代码功能的演示,可以观看此youtube视频。下面是对安装和使用它的更详细和最新的描述。当前源代码和二进制文件尚未实现所有“四大设计模式”。如果您想体验所有这些模式,它们可以在Codeplex的下载中获得90天的试用版,支持C#和VB.NET(目前是这样)。
安装插件/扩展
如果您只使用VS 2015或2017,您可以仅下载压缩的扩展,解压.vsix文件并运行它。
或者,您可以选择IDE中的'工具'菜单,然后选择'扩展和更新...',打开'联机'选项卡,并在搜索框中键入“design patterns”。此扩展应显示在顶部,如果您选择了它,您可以直接从那里安装。
对于旧版本,请先从本页或Codeplex下载当前的安装存档,然后解压。您应该会注意到下载中包含TemplateLibrary.zip文件,以及其在Misc目录下的相应展开文件夹。该文件夹包含模式模板,我们将对其进行修改,以便在安装脚本中添加您自己的模板,如下所示。
最好在安装前关闭Visual Studio,并卸载之前安装过的该插件的任何先前版本。
此外,以管理员身份运行似乎可以使安装过程更顺利。如果您仍在使用Windows XP,请在与您使用的Visual Studio版本对应的文件夹中查找setup.exe,否则只需启动install.bat并选择您的版本。安装过程中会弹出一个对话框,让您选择菜单位置和要使用的编程语言。您可以保留默认设置并继续,或选择语言提供程序、命令位置等。
对于VS2015和2017,您无需执行任何特定操作,因为您可以选择选项5或直接运行.vsix文件。其余设置将在您首次启动扩展时触发。
从版本9(2008)到12(VS2013)的每个Visual Studio版本都有一个特定的插件或扩展。其各自版本的卸载链接应显示在Windows启动菜单下。此外,如果由于某种原因该插件在加载项目后或在“管理插件”Visual Studio菜单中未显示,则在Start\DesignPatterns\Uninstall Design Patterns for 20XX下提供了一个“重置插件”菜单。对于VS 2015和2017,您只能从IDE的“工具”菜单中卸载此扩展。
如果您对某些语言不感兴趣,可以从配置选项卡中取消选中相应的提供程序来删除它们。您需要重新启动Visual Studio才能看到更改。
将模式插入当前项目
安装后,在Visual Studio中打开一个现有项目。支持的项目类型有VB、C#、原生C/C++和CLI/C++。
右键单击正在工作的项目,选择添加设计模式...,或在“工具”或“项目”主菜单下查找相同的菜单项。
一个类似下图的窗口应该会打开。在标题中,您应该看到当前项目及其编程语言。
您可以通过使用表单左上角的组合框筛选模式来缩小到您需要的模式。
这些过滤器可以通过单击“隐藏过滤器”或“显示过滤器”按钮来隐藏或显示。
通过右键单击特定的网格单元格或网格的标题,可以实现相同的筛选。
您还可以通过单击网格的列标题来重新排序。键入模式的第一个字母将聚焦于具有匹配PatternName
的行。如果底部网格过于混乱,您还可以通过右键单击其标题来隐藏您不关心的列。选择一个模式,然后单击“下一步”。
在此屏幕上,您可以根据需要更改某些参数的值(默认值是有效的,您以后可以在IDE中重构C#或VB.NET等语言)。再次选择下一步,您将有机会看到代码的样子。
您可以通过单击上一步按钮返回,或选择生成以将代码文件插入到当前的Visual Studio项目中。
配置按钮允许您选择弹出菜单的位置或通过调用“配置”表单(如前所示)进行其他自定义。
添加您自己的模式模板
模式模板的存储方式
在添加新模式之前,您需要了解现有模式的工作方式。
模式模板及其XML描述通常存储在安装后的C:\Program Files (x86)\Software Fantasies\DesignPatterns for VS 20XX\TemplateLibrary中。
元数据存储在XML文件中,如CSharpTemplates.xml,文件名与目标语言匹配
<?xml version="1.0" encoding="utf-8"?>
<PatternTemplates PatternsVersion ="1.3">
............
<PatternTemplate CodeLang="CSharp" PatternName="Singleton">
<PatternProperties>
<PatternAlias>Singleton</PatternAlias>
<MinVSVersion>9.0</MinVSVersion>
<OnlineResources>http://msdn.microsoft.com/en-us/library/ff650316.aspx</OnlineResources>
<CompilerSyntax>C# 2.0</CompilerSyntax>
<ProgrammingStyle>static initialization</ProgrammingStyle>
<Category>Creational</Category>
</PatternProperties>
<FileTemplates>
<FileTemplate FileItemName="Singleton.cs">SingletonTemplate.cs</FileTemplate>
</FileTemplates>
<TemplateArguments>
<TemplateArgument ArgumentName="RootNamespace"
IsRuntime="True" Description ="NameSpace"/>
<TemplateArgument ArgumentName="Singleton" IsRuntime="false"
Description ="Singleton class Name">ConcreteSingleton</TemplateArgument>
</TemplateArguments>
</PatternTemplate>
......
</PatternTemplates>
在上面的XML片段中,您将识别出主表单的gridview
中显示的列。缺失元素的某些默认值基于PatternName
属性中描述的模式名称。负责加载模式模板的大部分代码如下所示
public virtual void Init(ILanguageProvider languageProvider, XElement templateElem)
{
//.....
PatternName = templateElem.Attribute("PatternName").Value;
try
{
try
{
this.CodeLanguage = (CodeLangEnum)Enum.Parse(typeof(CodeLangEnum),
templateElem.Attribute("CodeLang").Value, true);
}
catch
{
CodeLanguage = CodeLangEnum.Unsupported;
}
var properties = templateElem.Element("PatternProperties");
PictureStoredAs = DefaultStorage;
DescriptionStoredAs = DefaultStorage;
Culture = "eng";
MinVSVersion = _fCtrVSVersion;
if (properties != null)
{
float minVSVer = _fCtrVSVersion;
foreach (XElement e in properties.Elements())
{
switch (e.Name.ToString())
{
case "PatternAlias":
PatternAlias = e.Value;
break;
case "MinVSVersion":
if (!float.TryParse(e.Value, out minVSVer))
minVSVer = _fCtrVSVersion;
MinVSVersion = minVSVer;
break;
case "Picture":
_iRepository.GetPicture(this, e);
break;
case "OnlineResources":
OnlineResources = e.Value;
break;
case "CompilerSyntax":
CompilerSyntax = e.Value;
break;
case "ProgrammingStyle":
ProgrammingStyle = e.Value;
break;
case "Description":
_iRepository.GetDescription(this, e);
break;
case "Category":
Category = e.Value;
break;
case "Culture":
Culture = e.Value;//"eng" if missing
break;
default:
break;
}
}
}
//fill in with defaults
IProjectInfo projectInfo = _languageProvider.GetAsService<IProjectInfo>();
if (OnlineResources == null)
{
OnlineResources = string.Format(@"www.bing.com/search?q={0}+
software+design+pattern+{1}", PatternName, projectInfo.CodeLang);
}
if (Description == null)
{//try adding default file if value not in xml file
_iRepository.GetDescription(this, null);
}
if (Picture == null)
{//try adding default file if value not in xml file
_iRepository.GetPicture(this, null);
}
if (ProgrammingStyle == null)
{
ProgrammingStyle = "Plain";
}
if (PatternAlias == null)
{
PatternAlias = PatternName;
}
LoadCodeTemplates(templateElem);
}
catch (Exception ex)
{
IWin32Window iwnd = _languageProvider.GetAsService<IWizardWindow>() as IWin32Window;
iwnd.ShowMessageBox(ex.Message, "Can not initialize template " + PatternName);
}
}
您会注意到缺失元素的默认值:MinVSVersion
(9.0)、ProgrammingStyle
(Plain)、PatternAlias
(模式名称的值)、Culture
(eng)和OnlineResources
会自动生成。您必须填充的最小值是CompilerSyntax
、ProgrammingStyle
和Category
。
对于Description
,默认文件名是通过将PatternName
与.txt、.rtf或.html/.htm连接而生成的(以找到的第一个为准)。如果找不到具有该名称和其中一个扩展名的文件,则描述将作为Url
类型StoredAs
,其值与OnlineResources
相同。这样,即使您没有匹配的文件,或者Text
类型的StoredAs
描述,您仍然会得到一些东西显示在HTML控件中。
因此,添加一个有效的OnlineResources
元素以导航到正确的页面是一个好主意,如果您不提供本地文件作为描述。使用本地htm或html文件将为您带来额外的优势,即在生成的源代码中将Intent
段落的文本作为注释插入,并且如果文档结构相同,还可以提供可折叠的标题。
对于Picture
,默认文件名是通过将PatternName
与.png、.bmp或.jpg/.jpeg连接而生成的(以找到的第一个为准)。
内容文件遵循相同的规则,扩展名根据模式的CodeLang
属性为.h、.cs或.vb类型。这些文件位于与模式名称匹配的子目录中。
添加模板模式
由于实现的已设计模式列表并不全面,而只是一个起点,因此我将描述如何添加自己的新模式模板,包括描述、代码、图片以及可选参数。
- 首先,向对应于目标语言的XML文件添加一个新的
PatternTemplate
条目。然后添加另一个名为PatternProperties
的XML元素。如果您至少填写了PatternName
、CodeLang
、Category
、ProgrammingStype
和CompilerSytax
,您应该能够在表单的gridview
中看到它们以及默认值。所有特定于模式的文件都将放在同名文件夹中,例如C:\Program Files (x86)\Software Fantasies\DesignPatterns for VS 2013\TemplateLibrary\Singleton。对于vsix扩展,您应该在Misc子文件夹中执行相同操作。 - 对于
Description
,如果您不喜欢上面提到的回退到OnlineResources
,您可以首先将SavedAs
属性设置为Text
,并在节点的值中指定内容。这作为开始是好的,但最终您会创建一个名为模式名称的html、rtf或txt文件。使用现有的htm文件作为您自己的软件模式的模板是一个好主意。 - 添加带有类图的图片,并且文件名与模式相同。如果重新启动Visual Studio,向导表单应该会正确填充。
- 在添加源代码之前,我重申您应该将默认自动生成的Web链接Online Resources更改为您喜欢的链接。
- 在每个模式文件夹中,您将为需要添加模式的每种语言创建一个子文件夹,如VB、CSharp和CPP。后者包含
NativeCpp
和ManagedCPP
示例。编程语言在PatternTemplate
元素的CodeLang
属性中指定。只需添加模式名称与“Template
”连接的文件名,并为相应的语言添加正确的扩展名,例如.cs、.vb或.h。
此时,按照向导,您应该能够将创建的文件插入到选定的项目中。如果出现错误,您应该使用其他模板元素和语言子文件夹作为示例来查找错误。
添加模式的参数和多个文件
到目前为止,您看到可以向选定的项目添加一个文件,其内容由您决定。对于C#或VB.NET来说,这可能没问题,因为您可以稍后使用IDE内置的重构功能轻松更改类名和成员名。对于C++和其他语言,这种情况不受支持,通常您希望一次插入多个文件,而不仅仅是一个头文件。因此,引入了文件模板和模板参数的概念。以下是如何添加它们
- 向
PatternTempate
元素添加一个名为FileTemplates
的元素。然后向其中添加名为FileTemplate
的元素。FileItemName
属性是将保存在磁盘和项目中的名称。元素的值是包含源代码的模板的文件名。 - 向
PatternTempate
元素添加一个名为TemplateArguments
的元素。然后向其中添加名为TemplateArgument
的元素。相应地填充ArgumentName
、IsRuntime
、Description
和值。当您在向导表单上单击“下一步”时,这些属性将显示出来。只有值可以通过编辑进行更改,并将允许重命名指定的成员。唯一的Runtime
参数是RootNamespace
,它保存项目的默认命名空间。其他参数是自定义的,它们将替换文件模板中标记的文本。 - 在要插入的源代码文件中,通过添加以
$
字符为前缀和后缀(例如,Bridge变为$Bridge$
)来替换目标成员的string
。不带$
的string
将成为ArgumentName
,其替换值将是TemplateArgument
的值。所有参数都位于PatternTemplate
级别,而不是特定于每个FileTemplate
。
改进模式模板创建
到目前为止描述的流程的缺点是,由于内存缓存,您需要为对XML文件或源代码文件模板的每次更改重新启动Visual Studio。如果您忘记了这一点,您将看不到您的更改。
为了避免这种情况,我创建了一个名为VSEmulator.exe的程序,它将托管向导表单并执行Visual Studio的所有操作,除了将文件插入到项目中。此可执行文件接受项目名称作为参数,以决定使用哪种语言。这是改进的创建过程
- 从codeplex TFS获取源代码,并将C:\Program Files (x86)\Software Fantasies\DesignPatterns for VS 20XX\TemplateLibrary的内容复制到您通过导入源代码创建的Misc文件夹中。或者,您可以将下载的TemplateLibrary.zip解压缩到Misc文件夹中,这样新的目录路径将类似于..\DesignPatterns\Misc\TemplateLibrary。如果您之前是从TFS获取的,则可以跳过此步骤。对于VS扩展,请仅使用Misc文件夹。
- 如果您之前安装过,请通过选择Startup Menu并单击链接Start\DesignPattern\Uninstall Design Patterns for 20XX来卸载Design Patterns。这是为了避免不同文件路径之间的冲突。
- 打开正确版本的
DesignPatterns_vXX
解决方案并生成它。将VSEmulator_VXX
设置为启动项目,并将参数设置为所需的项目文件名(可以是虚构的),然后运行它。现在您可以轻松地立即在本地TemplateLibrary文件夹中看到上述更改的结果。 - 当您认为模式已最终确定(您可以编译生成的代码)时,您可以将启动项目更改为
DesignPatterns_vXX
并运行它。您应该能够在IDE(上下文菜单或下拉菜单)中看到更改,然后您可以插入或查看您创建的新模板源代码。 - 添加完模板后,您可以重新启动Visual Studio并生成安装包,方法是生成
DesignPatternsSetup_VXX
。这适用于VS 2008和2010,但对于新版本,您需要进入Misc文件夹并运行buildAll.bat来构建所有内容。这是构建安装脚本的最佳方法,但如果您不想构建所有内容,您可以直接将..\DesignPatterns\Misc\TemplateLibrary文件夹压缩到TemplateLibrary.zip存档中,并用您的新存档替换安装文件夹中的旧TemplateLibrary.zip。现在您可以运行install.bat并看到您的新模板模式。
您添加的模板不一定是面向对象的“设计模式”。它可以是您想要的任何内容:服务、自定义类等。您只需要为不适合现有模型的新类别命名。
使用快速在线搜索
如何使用它
同一个插件/扩展允许您选择文本、错误或引用,右键单击它,然后在网上搜索,而无需复制粘贴到搜索引擎中的额外步骤。此外,您还可以选择将结果直接显示在Visual Studio的内部浏览器窗口或您在配置表单中选择的默认Windows浏览器中,并选择要在配置网格中使用的搜索网站。
实现
这里简要介绍了在插件的OnConnection
调用期间如何实现此功能。
private void CreateSearchMenus(DTE2 _applicationObject)
{
var menus = MEFController.Instance.SearchProviders.Select(p => new
{
SearchProviderName = p.Metadata.SearchProviderName,
URL = p.Metadata.URL,
SupportedWnds = p.SearchLocations,
SP = p,
});
WindowPopupEnum[] allLocations = Utils.GetAllEnumValues<WindowPopupEnum>();
var VSWindows = new[]
{
new {VSWndType = WindowPopupEnum.CodeWindow, Caption ="Search Selection Online"},
new {VSWndType = WindowPopupEnum.XAMLEditor, Caption ="Search Selection Online"},
new {VSWndType = WindowPopupEnum.ReferenceItem, Caption ="Search Reference Online"},
new {VSWndType = WindowPopupEnum.ErrorList, Caption ="Search Error Online"} ,
new {VSWndType = WindowPopupEnum.HTML, Caption ="Search Selection Online"} ,
};
try
{
for (int j = 0; j < VSWindows.Length; j++)
{
if (VSWindows[j].VSWndType == WindowPopupEnum.None)
continue;//no popUp for this VS window
CommandBar oCommandBar = ((CommandBars)_applicationObject.CommandBars)
[VSWindows[j].VSWndType.GetDescription()];
//Add the main menu
CommandBarPopup oPopup = (CommandBarPopup)
oCommandBar.Controls.Add(MsoControlType.msoControlPopup,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value, 1, true);
oPopup.Caption = VSWindows[j].Caption;
CommandBarButton self = oPopup.Control as CommandBarButton;
//Add a separator line
oPopup.BeginGroup = true;
//Add the search menus (sub-item)
int pos = 0;
foreach (SearchProvider item in MEFController.Instance.SearchProviders)
{
SearchProvider searchProvider = item;//this assignment avoids lambda
//iteration bug in VS2008, otherwise only the last element is yielded
if ((VSWindows[j].VSWndType & searchProvider.SearchLocations) == WindowPopupEnum.None)
continue;
pos++;
//Add the search menus (sub-item)
CommandBarButton oControl =
(CommandBarButton)oPopup.Controls.Add(MsoControlType.msoControlButton,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value, pos, true);
oControl.Caption = searchProvider.Metadata.SearchProviderName;
oControl.Tag = searchProvider.Metadata.URL;
oControl.TooltipText = "Search " + searchProvider.Metadata.SearchProviderName +
" for...";
oControl.Click += new _CommandBarButtonEvents_ClickEventHandler
((CommandBarButton ctrl, ref bool c) =>
{
DTE2 dte = (ctrl.Application as DTE2);
if (dte == null)
return;
object oContext = WindowPopupEnum.None;
SearchProvider.Context context =
dte.ActiveWindow.GetSelectedContext(searchProvider);
if (!string.IsNullOrEmpty(context.SelectedText))
{
try
{
ItemOperations itemOperations = dte.ItemOperations;
if (itemOperations != null)
{
string navigationUrl = searchProvider.GetNavigationUrl(context);
switch (Utils.OnlineSearchDestination)
{
case 1:
System.Diagnostics.Process proc =
new System.Diagnostics.Process();
proc.StartInfo = new ProcessStartInfo(navigationUrl);
proc.Start();
break;
case 2:
Window window = itemOperations.Navigate
(navigationUrl, vsNavigateOptions.vsNavigateOptionsDefault);
break;
default:
break;
}
}
}
catch
{}
}
});
if (!_commandBarButtons.Any(kv => kv.Key == searchProvider.Metadata.SearchProviderName))
_commandBarButtons.Add
(searchProvider.Metadata.SearchProviderName, oControl);//save subitem from
//garbage collection in VS2008
}
pos++;
//Add the search menus (sub-item)
CommandBarButton cControl =
(CommandBarButton)oPopup.Controls.Add(MsoControlType.msoControlButton,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value, pos, true);
cControl.Caption = "Configure Online Search menus";
cControl.Tag = null;
cControl.TooltipText = "Search Configuration";
cControl.Click += new _CommandBarButtonEvents_ClickEventHandler
((CommandBarButton ctrl, ref bool c) =>
{
using (ConfigForm cfg = new ConfigForm(3))
{
cfg.ShowDialog(this);
}
});
if (!_commandBarButtons.Any(kv => kv.Key == "SearchConfig " +
VSWindows[j].VSWndType.GetDescription()))
_commandBarButtons.Add("SearchConfig " + VSWindows[j].VSWndType.GetDescription(),
cControl);//save subitem from garbage collection in VS2008
oPopup.BeginGroup = false;
}
}
catch (Exception ex)
{
Logging.Instance.Log(1, "Exception thrown in CreateContextMenu :{0}", ex.Message);
}
}
对于VS 2015及更高版本,它使用一个扩展,此代码略有不同。以下描述了一个搜索提供程序。所有这些都类似,并且是SearchProvider
的子类。
public class SearchProvider
{
public class Context
{
public string SelectedText { get; set; }
public string Caption { get; set; }
public IProjectInfo ProjectInfo { get; set; }
public string Suffix { get; set; }
public string SearchPhrase
{
get
{
if (string.IsNullOrEmpty(Suffix))
return SelectedText.Trim();
else
return string.Format("{0} {1}", SelectedText.Trim(),
Suffix);//only for code and error window, not XAML or references
}
}
}
public Context CreateContext(IProjectInfo prInf)
{
Context ctx = new Context() { Suffix = null, ProjectInfo = prInf,/*SP = this,*/ };
return ctx;
}
protected virtual WindowPopupEnum DefaultSearchLocations
{
get
{
return Utils.AllPopUpWnds;
}
}
public WindowPopupEnum SearchLocations
{
get
{
WindowPopupEnum loc = DefaultSearchLocations;
RegistryKey reg = Registry.CurrentUser.OpenSubKey
(string.Format("{0}\\{1}", Common.Utils.AppHive, Metadata.SearchProviderName), false);
if (reg != null)
{
object obj = reg.GetValue("SearchLocations", loc, RegistryValueOptions.None);
loc = (WindowPopupEnum)System.Convert.ToUInt32(obj);
loc &= Metadata.SupportedWnds;
reg.Close();
}
return loc;
}
set
{
RegistryKey reg = Registry.CurrentUser.CreateSubKey(string.Format("{0}\\{1}",
Common.Utils.AppHive, Metadata.SearchProviderName), RegistryKeyPermissionCheck.Default);
if (reg != null)
{
reg.SetValue("SearchLocations", (uint)(value & Metadata.SupportedWnds),
RegistryValueKind.DWord);
reg.Close();
}
}
}
public ISearchProviderMetaData Metadata { get; protected set; }
public string GetNavigationUrl(Context context)
{//add more from Context
return Metadata.URL + Uri.EscapeUriString(context.SearchPhrase).Replace
("#","%23").Replace("/","%2F").Replace("+","%2B"); ;
}
internal SearchProvider()
{
if (this.GetType() != typeof(SearchProvider))
{
string type = this.GetType().Name;
Metadata = MEFController.Instance.GetProviderSearchMetadata(type);
}
}
}
[ExportSearchProvider(SearchProviderName = "Google",
Description = "Google search provider", URL = "http://www.google.com/search?q=",
SupportedWnds = Utils.AllPopUpWnds)]
public sealed class Google : SearchProvider
{
protected override WindowPopupEnum DefaultSearchLocations
{
get
{
return WindowPopupEnum.CodeWindow | WindowPopupEnum.ErrorList |
WindowPopupEnum.HTML | WindowPopupEnum.XAMLEditor;
}
}
private Google()
{ }
}
只需创建类似的注释适当的类,就可以轻松添加自己的搜索提供程序。这样,它们就会显示在配置网格和弹出菜单中。
关注点
源代码相当庞大,我建议使用codeplex TFS repository来获取最新版本,而不是提供的zip文件。已发布的安装脚本也是如此。目前,仅实现了C#、VB、原生C++和C++\CLI的一些面向对象模式,但您可以根据上述说明自己添加它们,或者通过下载最新的90天试用版来获取其余的“四大设计模式”。
到目前为止,我只在Windows 7 64位和Windows XP 32位上测试过它。
如果第一次调用插件未能正确加载,请重新启动Visual Studio。
如果错误仍然存在于VS 2008 - 2013版本中,并且此插件未显示在菜单或“管理插件”Visual Studio菜单中,则在Windows的开始菜单中有一个“重置Visual Studio插件”菜单 - >DesignPatterns\VS20XX来修复此问题。
如果在Visual Studio(2008至2013)启动时仍然看到错误,请从VS命令提示符运行“devenv /resetaddin *
”命令。更多文档可以在这里找到。对于VS 2015和2017,可以从VS菜单“工具”->“扩展和更新...”->“设计模式扩展”->“卸载”来卸载此扩展,或者通过运行install.bat重新安装。
如果使用VS 2015或2017,您可以使用相应的DesignPatterns_v14.sln或DesignPatterns_v15.sln文件轻松地从源代码重建解决方案。
历史
- 2014年5月7日:版本1.91 - 首次发布
- 2014年8月22日:版本1.93添加了一些UI改进
- 2014年11月13日:版本1.93添加了一些UI改进,版本1.94为缺失的“四大设计模式”的C#和VB.NET添加了60天的试用版
- 2015年2月:版本1.95添加了快速在线搜索菜单
- 2015年5月:版本1.97改进了项目类型检测,并在代码生成中添加了模式描述
- 2015年5月:版本1.98添加了参数验证、更多配置选项、可折叠标题和模式交叉引用
- 2015年9月:版本2.0和2.10添加了一个可供VS 2015使用的扩展,以及一些小的修复和功能
- 2017年5月:版本2.14更改了扩展以支持VS 2015和2017。此外,我还添加了一个通过右键单击项目引用来搜索NuGet的选项。
此网站上的最后一个版本可能不是最新的,因为最最新的代码在Codeplex上。此外,此扩展的另一个链接在Visual Studio Gallery上。在那里,您可以获得一个额外的程序集,提供更多具有试用许可的模式。