Click here to Skip to main content
11,430,908 members (80,775 online)
Click here to Skip to main content

Visual Studio Design Patterns add-in

, 4 Mar 2015 Ms-PL
Rate this:
Please Sign up or sign in to vote.
A Visual Studio add-in that inserts some commonly known OO paterns into your working project and more.

 

 

*I recommend that you download the latest code and binaries from codeplex TFS.
Full disclosure: If you downloaded the code from codeproject(Version 1.95) you will have all the code, build and installation scripts to start extending/changing it as I'll describe below in this article.
The caveat is you have only some of the design patterns of the Gang of four.
If you got it from codeplex or Visual Studio Gallery you will get a newer version (1.96) that includes the missing paterns but they come with a 60 day trial.

 

 

Introduction

If you have been programming using a object oriented language, then you must have heard of design patterns. There are a number of books and web sites on this topic, but while using Visual Studio, you would have to go out of the IDE, refresh your memory about what a particular software pattern does and type or copy the code for it.
Wouldn't be easier to have an integrated Visual Studio tool to help you select the right pattern and insert the code for you with only a few clicks?
This is exactly what this Visual Studio add-in does: it indexes some commonly known OO patterns like the Gang's of four, presents them in easy to search user interface and inserts the code into your working project.
It provides you with parameters to further customize the patterns and it works for languages supported by Visual Studio like C#, VB.net, C++ flavors and can be extended to other Visual studio supported languages like F#.
Additionally this add-in also provides some unrelateted functionality like the ability to easily search online the selected text or item from code, xml, html, error or references windows. The express versions of Visual Studio are unable to use this add-in, but all the premium or community editions could.

Background

I've created this Visual Studio add-in to act as a convenience feature for people using the Microsoft IDE (the express versions do not support add-ins). If you download the binaries or the code from 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 and 2013 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.

Since the code base is very large as you can see in the codeplex repository, I'm only going to focus on usage and the addition of new patterns to the existing ones this time. If this article spurs enough interest I will come back with a sequel for creating custom assemblies for further customization, licensing, etc.

Using the add-in

If you are in rush to see a demo of what this code does you can watch this youtube video. Below is a more detailed and up to date description of what is going on when installing and using it. The current source code and binaries do not have all the Gang of four design patterns implemented. If you want to experience all of them, they are available on a 60 day trial in a download from codeplex for C# and VB.net (so far).

Installing the add-in

Start by downloading the current installation archive, from this page or codeplex and unzip it. You should notice the presence of TemplateLibrary.zip file in the download. That is the file holding the pattern templates and will be the target of our change in order to add your own templates to the installation script as you will see later.
It's best to close Visual Studio before the installation and uninstall any previous version of this add-in if you had one already.
 If you are still using Windows XP, look for setup.exe in the folder(s) corresponding to the same Visual Studio version(s) you are using, otherwise just start the install.bat and make your version selection. You will be presented with dialog during the installation to select the menu positions and the programming languages you wish to use. You can keep the defaults and continue or choose the language providers, command positions, etc.


There is a specific add-in for each version of Visula Studio starting wirth version 9 (2008). An uninstall link for its respective version should show up under  windows startup menu. Also a 'Reset Add-in' menu in the Start\DesignPatterns\Uninstall Design Patterns for 20XX is provided in case for some reason this add-in does not show up in the menus and the 'Manage Add-ins' Visual Studio menu.

Also, if some languages are of no interest to you, you can remove their respective provider by unchecking it from the configuration tab. You will have to restart Visual Studio to see the changes.

Inserting a pattern into the current project

After installing it, open an existing project in Visual Studio. Supported project types are VB, C#, native C/C++ and CLI/C++.
Right click on the working project and select Add DesignPatterns... or look for the same menu entry under the Tools or Project main menu.

A Window resembling the image below should open. In the title you should see current project and its programming language.

You can narrow down to the pattern you need by filtering the patterns using the combo boxes on the top left of the form.
These filters can be hidden or shown by clicking on the Hide or Show Filters button.
The same filtering can be achieved by right clicking on the specific grid cell or on the grid's headers.
You can also reorder by clicking on the column headers of the grid. Typing the first letter of the pattern will focus on the row with the matching PatternName. If the bottom grid was too cluttered, you can also hide the columns you are not interested in from the same form. Select one pattern and click Next.

On this screen you can change the values of some parameters should you needed it (defaults are valid, you can always refactor them later in the IDE for languages like C# or VB.Net). Select Next again and you have a chance to see how the code will look like.
You can go back by clicking on the Previous button, or select Generate to insert the code files into the current Visual Studio project.
A Configuration button allows you can choose where to place the Pop-up menus by invoking the Configuration form as shown before.

Add your own pattern template

How the patterns templates are stored

Before adding new patterns you need to understand how the existing ones work.
The pattern templates and their XML descriptions are usually stored in C:\Program Files (x86)\Software Fantasies\DesignPatterns for VS 20XX\TemplateLibrary after the installation.
The metadata is stored in xml files like CSharpTemplates.xml, the name matching the target language:

<?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>

In the xml snippet above you will recognize the columns that appear on the gridview in the main form. Some default values for the missing elements are based on the pattern name as described in the PatternName attribute. Most of the code responsible for loading a pattern template is shown below:

 

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);
    }

}

You can notice the default values for the missing elements: MinVSVersion(9.0), ProgrammingStyle (Plain), PatternAlias ( the pattern name value), Culture (eng) and OnlineResources are automatically generated. The minimum you must populate are CompilerSyntax, ProgrammingStyle and Category.
For the Description, the default file name is generated by concatenating the PatternName with the .txt, .rtf or .html/.htm whichever is present. If a file with that name and one of those extensions can not be found, the description will became of StoredAs type as Url, with the value the same as the OnlineResources. This way even if you don't have a matching file, or a description with the StoredAs type as Text, you will still get something to display in the HTML control.
Hence it is a very good ideea to add a valid OnlineResources element to navigate to the right page if you don't provide a local file with the description.
For the Picture, the default file name is generated by concatenating the PatternName with the .png, .bmp or .jpg/.jpeg, whichever is present.
The content files are following the same rule, with the extension being of type .h, .cs or .vb based on the CodeLang attribute of the pattern. These files are in the subdirectories matching the pattern's name.

Add the template pattern

Since the list of designed patterns implemented is not comprehensive, but rather just a starting point, I'm going to describe how to add your own new pattern templates consisting of description, code, picture and later, the optional arguments.

  1. Start by adding a new PatternTemplate entry to the xml file corresponding to your target language. Then add another XML element called PatternProperties. If you fill at least the PatternName, CodeLang, Category, ProgrammingStype and CompilerSytax, you should be able to see them as well as the defaults in the gridview of the form. All the pattern specific files will go in the folder with the same name e.g. C:\Program Files (x86)\Software Fantasies\DesignPatterns for VS 2013\TemplateLibrary\Singleton
  2. For the Description, if you don't like the fallback to the OnlineResources mentioned above, you can start by setting the SavedAs attribute to Text and specify the content in the value of the node. That's good as a start, but eventually you would end up creating and html, rtf or txt file with the name of the pattern.
  3. Add a picture with the class diagram and the file name same as the pattern. If you restart Visual Studio, the Wizard form should be populated correctly
  4. Before adding the source code, I reiterate that you should change the default auto generated web link Online Resources to one of your liking.
  5. In each pattern folder, you'll create a subfolder for each language you need to add your pattern like VB, CSharp and CPP. The latter holds both NativeCpp and ManagedCPP samples. The programming language is specified in the CodeLang attribute of the PatternTemplate element. Just add a file name of Pattern name concatenated with 'Template' and add the proper extension for the respective language e.g. .cs, .vb or .h.

At this point, following the wizard, you should be able to insert the file you've created into the selected project. If you get errors you should use the other Templates elements and language subfolders as examples to find the errors.

Adding arguments and multiple files to the pattern

So far you saw that you could add a file to your selected project and that its content is up to you. That might be all right for C# or VB.net since you can later easily change class and member names using the built in refactoring of the IDE. For C++ and other languages this is not supported and usually you will want to insert multiple files at once not just one like a header. Hence the concept of file templates and template arguments is introduced. Here is how to add them:

  1. Add an element call FileTemplates to the PatternTempate element. Then add elements called FileTemplate to it. The FileItemName attribute is the name that will be saved on disk and in the project. The value of the element is the file name of the template with source code.
  2. Add an element call TemplateArguments to the PatternTempate element. Then add elements called TemplateArgument to it. Populate the ArgumentName, IsRuntime, Description and the value accordingly. These attributes will show up when you click Next on the Wizard form. Only the value can be changed by editing and will allow renaming of designated members. The only Runtime argument is RootNamespace and holds the default name space of the project. The other arguments are custom and they will replace text marked in the file templates.
  3. In the source code file to be inserted replaced the strings for targeted members by adding a prefix and suffix made of the $ character (e.g. Bridge becomes $Bridge$). The string without the $ will become the ArgumentName and the value to replace it will be the value of the TemplateArgument. All arguments are at the PatternTemplate level not specific to each FileTemplate.

Improving the pattern template creation

The drawback to the process described so far is that you will need to restart Visual Studio for each change made to the xml file or the source code file templates, because of the memory cashing that is going on. If you forget that, you won't see your changes.

To avoid that, I have created program called VSEmulator.exe that will host the wizard form and do everything the Visual Studio does, except for the inserting of the files into the project. This executable takes a parameter as a project name to decide which language to work with. Here is the improved creation process:

  1. Get the source code from codeplex TFS and copy the content from C:\Program Files (x86)\Software Fantasies\DesignPatterns for VS 20XX\TemplateLibrary into the Misc folder you've just created by importing the source code. As an alternative you can unzip the downloaded TemplateLibrary.zip into the Misc folder so the new directory path will look like ..\DesignPatterns\Misc\TemplateLibrary
  2. Uninstall the Design Patterns by selecting the Startup Menu by clicking the link Start\DesignPattern\Uninstall Design Patterns for 20XX
  3. Open the right version of the DesignPatterns_vXX solution and build it. Set the VSEmulator_VXX as the startup project, set the argument as a desired project file name(can be a fictitious one) and run it. Now you can easily see the results of the changes in the local TemplateLibrary folder, as described above immediately.
  4. When you think that you've got the pattern in the final shape (you can compile the generated code), you can change the startup Project to DesignPatterns_vXX and run it. You should be able to see the changes in the IDE (context or pull down menu), and be able to insert the new template source code you've created.
  5. When done adding templates you could restart Visual Studio and build the installation kit by building DesignPatternsSetup_VXX. That works for VS 2008 and 2010, but for the newer versions you will have to go in the Misc folder and run the buildAll.bat to build everything. This is the best way to build the installation scripts, but if you don't want to build everything, you can just zip the ..\DesignPatterns\Misc\TemplateLibrary folder into the TemplateLibrary.zip archive and replace the old TemplateLibrary.zip with your new one in the installation folder. Now you can just run install.bat and get to see your new template patterns too.

The templates you add need not be only OO design patterns. It can be any content you wish: services, custom classes, etc. You just need to come up with new name categories if they don't fit the preexisting mold.

 

Using the quick online search

How to use it

The same add-in allows you to select some text, error or reference, right click it and then  search online without the extra step of copying and pasting in a search engine. Additionally you have the option to display the results directly in Visual Studio's internal browser window as you have chosen in the configuration form above and also to select the the search sites in the configuration grid.

Implementation

Here it is briefly how this functonality was implemented during add-in's OnConnection invocation.

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 elemenent 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);
    }
}

One of the search providers is described below. All of them are similar and are subclasses of 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()
    { }    
   
}

It should be easy to add your own search providers by just creating similar classes annotated appropriately . This way they will show in the configuration grid and the pop up menu.

Points of Interest

The source code is quite large and I recommend using the codeplex TFS repository to get the latest, rather than the zip provided. Same is true for the released installation scripts. Currently only some OO patterns for C#, VB, native C++ and C++\CLI are implemented, but you can add them yourself based on the instructions given above, or just get the rest of the Gang of four patterns by downloading the latest trial.
So far, I have tested it only on Windows 7 64 bit and Windows XP 32 bit.
Should you see errors when Visual Studio starts, from the VS command prompt run "devenv /resetaddin *" command. If the first time you invoke the add-in won't load correctly, just restart Visual Studio. Also a 'Reset Visual Studio Add-in' menu in the Start\DesignPatterns\VS20XX is provided in case for some reason this add-in does not show up in the menus and the 'Manage Add-ins' Visual Studio menu.

History

 

  1. May 7, 2014:Version 1.91 - first release.
  2. August 22 2014: Version 1.93 added some UI improvements.
  3. November 13 2014:Version 1.93 adds some UI improvements and version 1.94 adds a 60 day trial for C# and VB.net for the missing patterns of the Gang of four.
  4. February 2015: Version 1.95 added quick online search menus.

The last version might not be the latest since the most up to date code is on codeplex. Also another link to this add-in is on Visual Studio Gallery.

 

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

dmihailescu
Software Developer (Senior)
United States United States
Decebal Mihailescu is a software engineer with interest in .Net, C# and C++.

Comments and Discussions

 
SuggestionGood article but Pin
Leigh Pointer10-Mar-15 0:15
professionalLeigh Pointer10-Mar-15 0:15 
GeneralRe: Good article but [modified] Pin
dmihailescu10-Mar-15 5:02
memberdmihailescu10-Mar-15 5:02 
GeneralRe: Good article but Pin
Member 568844311-Mar-15 7:35
memberMember 568844311-Mar-15 7:35 
GeneralRe: Good article but Pin
dmihailescu12-Mar-15 7:17
memberdmihailescu12-Mar-15 7:17 
GeneralRe: Good article but Pin
jackbrownii18-Mar-15 14:50
memberjackbrownii18-Mar-15 14:50 
GeneralRe: Good article but Pin
Andre Sanches (alvs)2-Apr-15 10:17
memberAndre Sanches (alvs)2-Apr-15 10:17 
SuggestionThank you, very useful! Vote 5 Pin
Dmitry Tsarevich27-Feb-15 11:03
memberDmitry Tsarevich27-Feb-15 11:03 
GeneralRe: Thank you, very useful! Vote 5 Pin
dmihailescu4-Mar-15 4:57
memberdmihailescu4-Mar-15 4:57 
GeneralMy vote of 5 Pin
BillWoodruff26-Feb-15 10:13
mvpBillWoodruff26-Feb-15 10:13 
GeneralRe: My vote of 5 Pin
dmihailescu26-Feb-15 10:37
memberdmihailescu26-Feb-15 10:37 
QuestionIs free or has a cost after 60 days? Pin
Oscar R. Onorato26-Feb-15 7:09
memberOscar R. Onorato26-Feb-15 7:09 
AnswerRe: Is free or has a cost after 60 days? Pin
dmihailescu26-Feb-15 8:56
memberdmihailescu26-Feb-15 8:56 
GeneralRe: Is free or has a cost after 60 days? Pin
BillWoodruff26-Feb-15 9:18
mvpBillWoodruff26-Feb-15 9:18 
GeneralRe: Is free or has a cost after 60 days? Pin
dmihailescu26-Feb-15 9:31
memberdmihailescu26-Feb-15 9:31 
GeneralMy vote of 5 Pin
_Vitor Garcia_26-Feb-15 5:27
member_Vitor Garcia_26-Feb-15 5:27 
QuestionCan you add it to NuGet Pin
AE~118-Feb-15 1:37
memberAE~118-Feb-15 1:37 
Answernot sure Pin
dmihailescu5-Mar-15 5:55
memberdmihailescu5-Mar-15 5:55 
QuestionMisleading tags? Pin
Mike Nordell2-Feb-15 9:19
memberMike Nordell2-Feb-15 9:19 
AnswerRe: Misleading tags? Pin
dmihailescu2-Feb-15 18:36
memberdmihailescu2-Feb-15 18:36 
GeneralRe: Misleading tags? Pin
Mike Nordell7-Feb-15 16:09
memberMike Nordell7-Feb-15 16:09 
GeneralMy vote of 5 Pin
popara18-Nov-14 17:17
memberpopara18-Nov-14 17:17 
GeneralMy vote of 5 Pin
Mahsa Hassankashi15-Nov-14 0:27
memberMahsa Hassankashi15-Nov-14 0:27 
GeneralMy vote of 3 Pin
Forogar 14-Nov-14 11:10
member Forogar 14-Nov-14 11:10 
GeneralRe: My vote of 3 Pin
dmihailescu14-Nov-14 12:17
memberdmihailescu14-Nov-14 12:17 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun13-Nov-14 20:17
memberHumayun Kabir Mamun13-Nov-14 20:17 
QuestionThat is realy great. Pin
musketier25-Aug-14 10:57
membermusketier25-Aug-14 10:57 
QuestionError when installing Pin
Member 22278021-Jul-14 12:15
memberMember 22278021-Jul-14 12:15 
AnswerRe: Error when installing Pin
dmihailescu1-Jul-14 12:41
memberdmihailescu1-Jul-14 12:41 
GeneralMy vote of 5 Pin
Ahmed Bensaid19-Jun-14 4:44
professionalAhmed Bensaid19-Jun-14 4:44 
GeneralMy vote of 5 Pin
Shemeer NS20-May-14 6:48
mvpShemeer NS20-May-14 6:48 
QuestionWin 8 64 bit support ? Pin
delphoiq19-May-14 22:59
memberdelphoiq19-May-14 22:59 
AnswerRe: Win 8 64 bit support ? Pin
dmihailescu20-May-14 5:09
memberdmihailescu20-May-14 5:09 
AnswerRe: Win 8 64 bit support ? Pin
Member 455443319-Oct-14 7:07
memberMember 455443319-Oct-14 7:07 
GeneralMy vote of 5 Pin
Raul Iloc16-May-14 3:16
mvpRaul Iloc16-May-14 3:16 
GeneralMy vote of 5 Pin
Prasad Khandekar13-May-14 2:38
professionalPrasad Khandekar13-May-14 2:38 
QuestionLooks very useful Pin
Forogar 8-May-14 4:38
member Forogar 8-May-14 4:38 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun8-May-14 1:57
memberHumayun Kabir Mamun8-May-14 1:57 
QuestionGreat Pluggin Pin
nilesh078-May-14 0:11
membernilesh078-May-14 0:11 
QuestionGreat article about the integrated Visual Studio tool (Design Patterns add-in) Pin
Volynsky Alex7-May-14 22:50
professionalVolynsky Alex7-May-14 22:50 
GeneralMy vote of 5 Pin
Klaus Luedenscheidt7-May-14 20:06
memberKlaus Luedenscheidt7-May-14 20:06 
GeneralRe: My vote of 5 Pin
dmihailescu8-May-14 4:30
memberdmihailescu8-May-14 4:30 
GeneralRe: My vote of 5 Pin
Klaus Luedenscheidt8-May-14 19:55
memberKlaus Luedenscheidt8-May-14 19:55 
GeneralMy vote of 4 Pin
Rajesh Varma Buddaraju7-May-14 19:55
memberRajesh Varma Buddaraju7-May-14 19:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150428.2 | Last Updated 4 Mar 2015
Article Copyright 2014 by dmihailescu
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid