I want you to know that your illustrious executive editor, Brad Jones, is looking out for you. I proposed this article in my quarterly column calendar and Brad asked me if this was going to be a drag-and-drop article. I answered: No.
His question illustrated why I wanted to write this article. Current versions of Visual Studio.NET support snippets—simply drag and drop some code into the toolbox and you can reuse it anytime you’d like. While useful, this function is not very exciting and it’s often overlooked. Code snippets in Visual Studio 2005, however, are far more useful and deserve your attention. Based on XML, they support replaceable parameters, allow inserting assembly references and imports statements, and enable better organization. They also let you share management with other developers easily.
This article is my meager effort to encourage you to take advantage of code snippets. It briefly demonstrates how to create a snippet in Visual Studio 2005 beta 2 using XML.
Half-Baked Beta Bumps
Beta means not quite finished. Think of beta applications as muffins pulled out of the oven before they are baked. Glaringly missing from the VS 2005 beta 2 is a code snippet editor. The official public statement is that the code snippet editor isn’t quite ready for users. While waiting for the final release of VS 2005, you can download an external code snippet editor that comes complete with source code from MSDN. The examples in this article use this sample VB code snippet editor, which you can use until VS 2005 ships with its built-in editor.
What Are Code Snippets?
A code snippet is exactly what it sounds like: a small piece of code. Like project templates and project item templates, code snippets are discrete chunks of written code. Also, like templates, code snippets support replaceable parameters, which permit you to customize a snippet for each context.
If you need whole projects or project items, you can use templates. For something smaller or just to show the code in IntelliSense and make it pluggable, use code snippets.
Create a Code Snippet
Code snippets are stored as XML in a file with a .snippet extension. Like all XML, these code snippet files have a specific format. Additionally, the snippet files need to be placed where Visual Studio can locate them. To this end, the snippet manager—which the final section covers—makes it easy to organize snippets.
XML, being based on SGML (Standard Generalized Markup Language), is an elegant concept but an ugly language that isn’t very human friendly. However, it is very useful in the Internet age because its text, its extensibility, and its predictable format-simply identify an opening tag and then fill in the blanks between the opening and closing tags. (Almost every tag has a symmetric closing tag with the same name and an additional forward slash (/).)
Snippets support tags for replaceable elements, but the simplest snippets—those that contain literal code with no parameters—just need the code you want to insert. This code is an attribute of the <Code> tag. Listing 1 contains a simple Hello, World! snippet. To create additional snippets, copy and paste the literal code in the [CDATA] attribute with the new snippet code.
Listing 1: XML for a Literal Snippet
<?xml version="1.0"?> <CodeSnippets > <CodeSnippet Format="1.0.0"> <Header> <Title>Canonical Hello, World! example</Title> </Header> <Snippet> <Code Language="VB"><![CDATA[MsgBox("Hello, World!")]]></Code> </Snippet> </CodeSnippet> </CodeSnippets>
Add Imports and References
You add imports and references after the <Snippet> tag. If you want to add an assembly reference, add a <Reference> tag with a nested <Assembly> tag followed by the name of the assembly (see Listing 2). Add <Import><Namespace> tags after the <Reference> tag. The <Imports> tag adds imports statements to the same module that you added the snippet to.
The excerpt in Listing 2 shows how to reference the System.Data.dll assembly and add an imports statement for the System.Collections namespace.
Listing 2: Elided Excerpt from a Snippet File Showing the Tags for an Assembly Reference and a Namespace Imports Statement
<?xml version="1.0"?> <CodeSnippets > <CodeSnippet Format="1.0.0"> <Header> <Title /> </Header> <Snippet> <References> <Reference> <Assembly>System.dll</Assembly> </Reference> </References> <Imports> <Import> <Namespace>System.Collections</Namespace> </Import> </Imports> <Declarations> ...
Add Literal and Object Replacements
Replacements represent elements of your snippet that the user has to provide. To identify a replacement, add a <Declarations> tag at the same level as the <References> and <Imports> tags. If the replacement is a literal, add a <Literal> nested tag; for objects, add an <Object> nested tag. Both literal and object tags include <ID>, <ToolTip>, and <Default> child tags, and the object tag has an extra <Type> child tag that indicates the type of the object.
Listing 3 shows a declarations section. Listing 4 shows a complete example demonstrating how to create a code snippet that generates a strongly typed collection.
Listing 3: Example Declarations Section for a Code Snippet
<Declarations> <Literal> <ID>SqlConnString</ID> <ToolTip>Replace with a SQL connection string.</ToolTip> <Default>"SQL connection string"</Default> </Literal> <Object> <ID>SqlConnection</ID> <Type>System.Data.SqlClient.SqlConnection</Type> <ToolTip>Replace with a connection object in your application. </ToolTip> <Default>dcConnection</Default> </Object> </Declarations>
Listing 4: Complete Code Snippet That Will Stub a Strongly Typed Collection
<?xml version="1.0"?> <CodeSnippets > <CodeSnippet Format="1.0.0"> <Header> <Title>Create a typed collection</Title> </Header> <Snippet> <References> <Reference> <Assembly>System.dll</Assembly> </Reference> </References> <Imports> <Import> <Namespace>System.Collections</Namespace> </Import> </Imports> <Declarations> <Literal> <ID>CLASS</ID> <Default>Customer</Default> </Literal> </Declarations> <Code Language="VB"><![CDATA[Public Class $CLASS$Collection Inherits System.Collections Public Default Property Item(ByVal Index As Integer) As $CLASS$ Get Return CType(List(Index), $CLASS$) End Get Set(ByVal Value As $CLASS$) List(Index) = Value End Set End Property Public Function Add(ByVal Value As $CLASS$) As Integer Return List.Add(Value) End Function End Class]]></Code> </Snippet> </CodeSnippet> </CodeSnippets>
I created the XML snippet file in Listing 4 by entering the code in Listing 5 in the editor tab of the snippets editor.
Listing 5: Using the Snippets Editor Is Easier Than Writing the XML from Scratch
Public Class $CLASS$Collection Inherits System.Collections Public Default Property Item(ByVal Index As Integer) As $CLASS$ Get Return CType(List(Index), $CLASS$) End Get Set(ByVal Value As $CLASS$) List(Index) = Value End Set End Property Public Function Add(ByVal Value As $CLASS$) As Integer Return List.Add(Value) End Function End Class
As you can see, using the editor is much simpler than writing the XML (in Listing 4). When Visual Studio 2005 ships, you will be able to select code from your projects and create a snippet directly from the code editor.
The Tools|Code Snippets Manager is a centralized manager for organizaing code snippets. You can add additional directories; import, add, and remove snippets; and search for snippets online.
Keep in mind that VS 2005 is still in beta, so some elements of the beta Code Snippets Manager may be a bit cantankerous. For now, all you can do is use the temporary code snippets editor and save your snippets to C:Documents and SettingsyourusernameMy DocumentsVisual StudioCode SnippetsVisual BasicMy Code Snippets. As long as you save the files with a .snippet extension and give them titles, they will show up in the IntelliSense snippets dropdown menu (see Figure 1).
Figure 1: The VB Code Snippets Editor
After you have created the .snippet file and copied it to the My Code Snippets folder, you can use the snippet to generate code. To insert the snippet, select Edit|Intellisense|Insert Snippet, navigate through the list of snippets—which are organized just as they are in the file system—and select the snippet (see Figure 2).
Figure 2: Ctrl K+Ctrl X Display the List of Snippets
After inserting the snippet, code elements that were marked as replaceable will be highlighted (see Figure 3). Replace the highlighted elements with the actual value. For example, if you want the Customer collection in Figure 3, you can leave the code as is. Otherwise, replace all of the highlighted instances of Customer with the type you will be collecting.
Figure 3: Replaceable Elements Are Highlighted
Snippets Have Come a Long Way
When you follow the examples in this article, keep in mind that VS 2005 is still in beta. Using beta software can be frustrating, but it can also be a lot of fun. Be patient.
In any case, I hope you got a sense of how far code snippets have evolved from simply copying and pasting text in the toolbox. They now offer manageable, shareable code with replaceable elements, assembly references, and imports statements. I’d say that makes for more than a simple a drag-and-drop article.
About the Author
Paul Kimmel is the VB Today columnist for www.codeguru.com and has written several books on object-oriented programming and .NET. Check out his upcoming book UML DeMystified from McGraw-Hill/Osborne (Spring 2005) and Expert One-on-One Visual Studio 2005 from Wrox (Fall 2005). Paul is also the founder and chief architect for Software Conceptions, Inc, founded 1990. He is available to help design and build software worldwide. You may contact him for consulting opportunities or technology questions at firstname.lastname@example.org.
If you are interested in joining, sponsoring a meeting, or posting a job, check out www.glugnet.org, the Web page of the Greater Lansing area Users Group for .NET.
Copyright © 2005 by Paul T. Kimmel. All Rights Reserved.