This post is inspired by my colleague Keith Burnell’s post on creating a ReSharper Template for View Model Properties with Annotations. His post really highlights how simple ReSharper makes it for you to create your own custom templates. However, I myself don’t use ReSharper because I don’t want Visual Studio to get any slower and all my needs are covered by the following extensions:
- Productivity Power Tools
- Web Essentials
- DPack (for its blindingly fast and ergonomic file and class navigation)
But I digress. My point is that as an avid non-user of ReSharper, I wanted to share the good news that if you can’t or won’t use ReSharper, you don’t have to miss out on the goodness of creating your own custom templates for Visual Studio. It’s just slightly more work. Actually, it’s really only slightly more work if you refuse to install any free extensions. See the last paragraph for an overview of two free snippet designer extensions I discovered while writing this post!
Creating the Template
- You could create a template from scratch, but there is a lot of boilerplate XML required, so I find that it’s easiest to start from an existing one instead. You’ll want Visual Studio to be in administrator mode for this. Within Visual Studio, choose File | Open… and navigate to this path (for VS 2013): “C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC#\Snippets\1033\Visual C#”.
- I already know that the “prop” snippet is pretty close to what I want, so I open “prop.snippet”. The file looks like this:
<?xml version="1.0" encoding="utf-8" ?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <CodeSnippet Format="1.0.0"> <Header> <Title>prop</Title> <Shortcut>prop</Shortcut> <Description>Code snippet for an automatically implemented property Language Version: C# 3.0 or higher</Description> <Author>Microsoft Corporation</Author> <SnippetTypes> <SnippetType>Expansion</SnippetType> </SnippetTypes> </Header> <Snippet> <Declarations> <Literal> <ID>type</ID> <ToolTip>Property type</ToolTip> <Default>int</Default> </Literal> <Literal> <ID>property</ID> <ToolTip>Property name</ToolTip> <Default>MyProperty</Default> </Literal> </Declarations> <Code Language="csharp"><![CDATA[public $type$ $property$ { get; set; }$end$]]> </Code> </Snippet> </CodeSnippet> </CodeSnippets>
Whew, that really is quite a lot of XML, isn’t it? Code snippets are quite powerful and this post will only be scratching the surface. To explore their full power, refer to the Code Snippets Schema Reference. For this post, the only areas we care about are Declarations and Code. - Modify the Code element content so it looks like this:
<Code Language="csharp"><![CDATA[[DisplayName("$displayName$")] public $type$ $property$ { get; set; }$end$]]> </Code>
All this does is create a potential placeholder for a declaration, but the IDE won’t treat it as one until you add a matching declaration to the Declarations section. - Add this markup to the Declarations section.
<Literal> <ID>displayName</ID> <ToolTip>Display name</ToolTip> <Default>MyDisplayName</Default> </Literal>
I copy-pasted one of the other ones and edited it. - Update the Title and Shortcut contents.
<Title>propd</Title> <Shortcut>propd</Shortcut>
I prefer to keep these both set to the same value. - Save the edited snippet as a new file. I prefer to give the file the same name as the Title and Shortcut above. This is where being in administrator mode helps since VS stores snippets in a protected folder. There is another place you can save snippet files within your user profile, but this causes the Surround With pop-up menu to start by showing “My Code Snippets” and “C# Code Snippets” folders instead of listing the shortcuts. I found this extremely annoying and prefer to save my custom snippets right alongside the rest of them to avoid this bifurcation.
- Test your new shortcut. No need to restart or refresh, Visual Studio picks up these changes immediately.
The final result of all the edits looks like this:
<?xml version="1.0" encoding="utf-8" ?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <CodeSnippet Format="1.0.0"> <Header> <Title>propd</Title> <Shortcut>propd</Shortcut> <Description>Code snippet for an automatically implemented property with a data annotation Language Version: C# 3.0 or higher</Description> <Author>Adam Anderson</Author> <SnippetTypes> <SnippetType>Expansion</SnippetType> </SnippetTypes> </Header> <Snippet> <Declarations> <Literal> <ID>displayName</ID> <ToolTip>Display name</ToolTip> <Default>MyDisplayName</Default> </Literal> <Literal> <ID>type</ID> <ToolTip>Property type</ToolTip> <Default>int</Default> </Literal> <Literal> <ID>property</ID> <ToolTip>Property name</ToolTip> <Default>MyProperty</Default> </Literal> </Declarations> <Code Language="csharp"><![CDATA[[DisplayName("$displayName$")] public $type$ $property$ { get; set; }$end$]]> </Code> </Snippet> </CodeSnippet> </CodeSnippets>
So looking back, it took quite a few more steps to create a custom snippet without the help of ReSharper, but in spite of that, the entire process takes only a few minutes.
Extra Credit
Let’s take advantage of the power of VS Code Snippets to add a little extra feature. If the System.ComponentModel namespace is not available, let’s fully qualify the DisplayName attribute. You can do this with a Code Snippet Function.
- Declare a literal that invokes the function:
<Literal Editable="false"> <ID>displayNameAttribute</ID> <Function>SimpleTypeName(global::System.ComponentModel.DisplayName)</Function> </Literal>
In this case, we don’t want this Literal to become highlighted as you tab through the editable fields, so you set Editable to false. - Replace the DisplayName attribute in the Code section with a reference to the Literal:
<Code Language="csharp"> <![CDATA[[$displayNameAttribute$("$displayName$")] public $type$ $property$ { get; set; }$end$]]> </Code>
- Save the snippet.
Once you edit an existing snippet, sometimes you have to give VS a little nudge to reload it. In my experience, simply opening Tools | Code Snippets Manager… and clicking OK does the trick. Now if you use this snippet in a file where System.ComponentModel is referenced, it will insert the short type name (“DisplayName”) but if it isn’t referenced, then it will use the fully qualified name. If you happen to be working in VB.NET, Code Snippets can even import namespaces and add assembly references! I wish that functionality was available in C# too, but at least it’s only a minor pain to import a namespace yourself.
So there you have it, complete instructions on how to create custom snippets with vanilla Visual Studio. While researching for this post, I also stumbled upon the existence of two free VS extensions that claim to make creating snippets easier. Snippetizer is an extension that works by letting you create a snippet using existing code as a template and perform the template editing and creation right inline. Snippet Designer is an open-source project that replaces the XML view of an opened .snippet file with a vastly simplified view that only shows the contents of the Code element in the code window and the rest of the snippet file is controlled by designers in the bottom pane and Properties window. You can duplicate Snippetizer’s functionality of using existing code as a starting point in Snippet Designer by selecting some code and choosing Export as Snippet from the context menu. Both give about the same level of control, but I suspect I would get frustrated with Snippetizer’s UI, which locks you into a modal editing experience until you save and close it, so I’m going to keep Snippet Designer installed for a while and see if I get enough value from it to keep it installed.
There are a lot of ways out there to write snippets. Which way works best for you?
The post Vanilla VS Snippet for a Property with a Data Annotation appeared first on Falafel Software Blog.