New information has been added to this article since publication.
Refer to the Editor's Update below.
.NET Tools
Ten Must-Have Tools Every Developer Should Download Now
James Avery
This article discusses:
|
This article uses the following technologies: .NET, C# or Visual Basic .NET, Visual Studio .NET |
Contents
Snippet Compiler
Regulator
CodeSmith
Building a Custom Template
NUnit
Writing an NUnit Test
FxCop
Lutz Roeder's .NET Reflector
NDoc
NAnt
NAnt in Action
Switch Tools
Conclusion
You cannot expect to build a first-class application unless you use the best available tools. Besides well-known tools such as Visual Studio® .NET, there are a multitude of small, lesser-known tools available from the .NET community. In this article, I'm going to introduce you to some of the best free tools available today that target .NET development. I'll walk you through a quick tutorial of how to use each of them, some of which will save you a minute here and there, while others may completely change the way that you write code. Because I am squeezing so many different tools into this single article, I will not be able to cover each of them extensively, but you should learn enough about each to decide which tools are useful for your projects.
Snippet Compiler
The Snippet Compiler is a small Windows®-based application that allows you to write, compile, and run code. This tool is useful if you have small pieces of code for which you don't want to create an entire Visual Studio .NET project (along with all the files that come with it).
As an example, let's say that I wanted to show you how to launch another application from the Microsoft® .NET Framework. In the Snippet Compiler I would start by creating a new file which creates a small console application. The snippet can be created inside the Main method of the console application, which is what I will do here. The following code snippet demonstrates how to create an instance of Notepad from the .NET Framework:
System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.StartInfo.FileName= "notepad.exe"; proc.Start(); proc.WaitForExit();
Of course this snippet would not compile by itself, but that is where Snippet Compiler comes into play. Figure 1 shows this code sample in Snippet Compiler.
Figure 1** Snippet Compiler **
To test this snippet, just press the play button (green triangle), and it will run in debug mode. The snippet will generate a console application popup, and Notepad will appear. When you close Notepad, the console application will close as well.
Personally, I have found Snippet Compiler to be invaluable when trying to create a small example for someone who has asked me for help, when normally I would have to create a project, make sure everything compiles, send them the code snippet, and then delete the project. Snippet Compiler makes this process much easier and much more pleasant.
Snippet Compiler was written by Jeff Key and can be downloaded from https://www.sliver.com/dotnet/SnippetCompiler.
Regulator
Regulator is the most recent addition to my top tools list. It is a full-featured tool that makes it easy to build and test regular expressions. There is a renewed interest in regular expressions because of the excellent support for them in the .NET Framework. Regular expressions are used to define patterns in strings based on characters, frequency, and character order. They are most commonly used as a means to validate user input or as a way to find a string of characters inside a larger string—for instance, when looking for a URL or e-mail address on a Web page.
Regulator allows you to enter a regular expression and some input against which you would be running this expression. This way you can see how the regular expression will act and what kind of matches it will return before implementing it in your application. Figure 2 shows Regulator with a simple regular expression.
Figure 2 Regulator
The document contains the regular expression, in this example it is [0-9]* which should match any number of digits in a row. The box in the bottom-right contains the input for this regular expression, and the box on the bottom-left shows the matches that this regular expression finds in the input. The ability to write and test regular expressions in a separate application like this is much easier than trying to work with them in your app.
One of the best features in Regulator is the ability to search the online regular expressions library at regexlib.com. For example, if you enter the string "phone" in the search box, you will find more than 20 different regular expressions that will match various phone numbers, including expressions for UK, Australian, and many other phone numbers.
Regulator was written by Roy Osherove and can be downloaded at https://osherove.com/tools.
CodeSmith
CodeSmith is a template-based code-generation tool that uses a syntax similar to ASP.NET to generate any type of code or text. Unlike many other code-generation tools, CodeSmith does not require you to subscribe to a particular application design or architecture. Using CodeSmith, you can generate anything from a simple, strongly typed collection to an entire application.
When you are building an application, you will often find yourself repeating certain tasks, whether it's writing data access code or building custom collections. CodeSmith is particularly useful at such times because you can write templates to automate those tasks and not only improve your productivity but also automate the tasks that are the most tedious to perform.
CodeSmith ships with a number of templates, including ones for all the .NET collection types as well as ones to generate stored procedures, but the real power of this tool comes from being able to create custom templates. To get you started, I'll provide a quick introduction to building a custom template.
Building a Custom Template
CodeSmith templates are simply text files which you can create in any text editor. Their only requirement is that they be saved with the .cst file extension. The sample template that I'm going to build will accept a string and then build a class based on that string. The first step to creating a template is to add the template header, which declares the language of the template, the target language, and a brief description of the template:
<%@ CodeTemplate Language="C#" TargetLanguage="C#" Description="Car Template" %>
The next part of the template is the property declarations, where you declare the properties that will be specified each time the template is run. With this template, the single property that I'm going to use is just a string, so the property declaration looks like this:
<%@ Property Name="ClassName" Type="String" Category="Context" Description="Class Name" %>
[Editor's Update - 6/16/2004: The code in Figure 3 has been updated to be safe for multithreaded operations.]
Figure 3 Class Generation
Custom Template
public sealed class <%= ClassName %> { private static volatile <%= ClassName %> _instance; private <%= ClassName %>() {} private static readonly object _syncRoot = new object(); public static <%= ClassName %> Value { get { if (_instance == null) { lock(_syncRoot) { if (_instance == null) { _instance = new <%= ClassName %>(); } } } return _instance; } } }
SingletonClass
public sealed class SingletonClass { private static volatile SingletonClass _instance; private SingletonClass() {} private static readonly object _syncRoot = new object(); public static SingletonClass Value { get { if (_instance == null) { lock(_syncRoot) { if (_instance == null) { _instance = new SingletonClass(); } } } return _instance; } } }
As you can see, the template will take the string input and generate a singleton class using that class name. In the template body, the same opening and closing tags are used as in ASP.NET. In this template, I am simply inserting the property value, but you can also use any type of .NET code inside these tags. Once the template is complete, you load it into CodeSmith by either double-clicking or opening it from the CodeSmith application. Figure 4 shows this template loaded into CodeSmith.
Figure 4 CodeSmith Template
You can see that the property on the left is the one I declared in the template. If I enter "SingletonClass" as the class name and click the Generate button, the class shown in the bottom part of Figure 3 will be generated.
CodeSmith is relatively easy to use and can produce some incredible results if applied correctly. One of the most common sections of an application that is targeted for code generation is the data access layer. CodeSmith includes a special assembly called the SchemaExplorer which can be used to generate templates from tables, stored procedures, or almost any other SQL Server™ object.
CodeSmith was written by Eric J. Smith and is available for download at https://www.ericjsmith.net/codesmith.
NUnit
NUnit is an open source unit testing framework built for the .NET Framework. NUnit allows you to write tests in the language of your choice to test a specific function of your application. Unit tests are an excellent way to test the functionality of your code when you first write it, and also to provide a method for regression testing of your application. The NUnit application provides a framework for writing unit tests, as well as a graphical interface to run these tests and view the results.
Writing an NUnit Test
As an example, I'm going to test the functionality of the Hashtable class in the .NET Framework to determine if two objects can be added and then retrieved. My first step will be to add a reference to the NUnit.Framework assembly, which will give me access to the attributes and methods of the NUnit framework. Next I'll create a class and mark it with the TestFixture attribute. This attribute lets NUnit know that this class contains NUnit tests:
using System; using System.Collections; using NUnit.Framework; namespace NUnitExample { [TestFixture] public class HashtableTest { public HashtableTest() { } } }
Next I'll create a method and mark it with the [Test] attribute so that NUnit knows that this method is a test. Then I'll set up a Hashtable and add two values to it, then use the Assert.AreEqual method to see if I can retrieve the same values that I added to the Hashtable, as shown in the following:
[Test] public void HashtableAddTest() { Hashtable ht = new Hashtable(); ht.Add("Key1", "Value1"); ht.Add("Key2", "Value2"); Assert.AreEqual("Value1", ht["Key1"], "Wrong object returned!"); Assert.AreEqual("Value2", ht["Key2"], "Wrong object returned!"); }
This will confirm that I can add and then retrieve values from the Hashtable—a simple test, but one that showcases the capabilities of NUnit. There are a number of test types, as well as various Assert methods, that can be used to test every part of your code.
To run this test, I'll need to build the project, open the generated assembly in the NUnit application, and then click the Run button. Figure 5 shows the results. I get a warm and fuzzy feeling when I see that big green bar because it lets me know that the test passed. This simple example shows how easy and powerful NUnit and unit testing can be. Being able to write a unit test that can be saved and rerun whenever you change code not only makes it easier for you to detect defects in your code, but the result is that you can deliver better applications.
Figure 5** NUnit **
NUnit is an open-source project that is available for download from https://www.nunit.org. There is also an excellent NUnit Visual Studio .NET add-in which allows you to run unit tests directly from Visual Studio. This can be found at https://sourceforge.net/projects/nunitaddin. For more information on NUnit and its place in test-driven development, see the article "Test-Driven C#: Improve the Design and Flexibility of Your Project with Extreme Programming Techniques" in the April 2004 issue of MSDN® Magazine.
FxCop
The .NET Framework is very powerful, which means there is great potential to create excellent applications, but there is equal opportunity to create poor programs. FxCop is one of the tools that can be used to help create better applications by enabling you to examine an assembly and check it for compliance using a number of different rules. FxCop comes with a set number of rules created by Microsoft, but you can also create and include your own rules. For instance, if you decided that all classes should have a default constructor that takes no arguments, you could write a rule that checks for a constructor on each class of an assembly. This way, no matter who writes the code, you will have a certain level of consistency. If you want more information on creating custom rules, see John Robbins' Bugslayer column on the subject in the June 2004 issue of MSDN Magazine.
So let's take a look at FxCop in action and see what it finds wrong with the NUnitExample assembly that I have been working with. When you open FxCop you first need to create an FxCop project and then add to it the assembly that you want to test. Once the assembly is added to the project, you can press Analyze, and FxCop will examine the assembly. The errors and warning found in this assembly are shown in Figure 6.
Figure 6 Errors and Warning Found by FxCop
FxCop found a couple of problems with my assembly. You can double-click on an error to see the details, including a description of the rule and where you can find more information. (Something you can do for fun is run FxCop on the Framework assemblies and see what turns up.)
FxCop can help you create better, more consistent code, but it cannot make up for poor application design or just plain poor programming. FxCop is also not a replacement for peer code review, but because it can catch a lot of errors before code review, more time can be spent on serious issues rather than having to worry about naming conventions.
FxCop was developed by Microsoft and is available for download from https://www.gotdotnet.com/team/fxcop.
Lutz Roeder's .NET Reflector
The next essential tool is called .NET Reflector, which is a class browser and decompiler that can examine an assembly and show you just about all of its secrets. The .NET Framework introduced reflection which can be used to examine any .NET-based code, whether it is a single class or an entire assembly. Reflection can also be used to retrieve information about the various classes, methods, and properties included in a particular assembly. Using .NET Reflector, you can browse the classes and methods of an assembly, you can examine the Microsoft intermediate language (MSIL) generated by these classes and methods, and you can decompile the classes and methods and see the equivalent in C# or Visual Basic® .NET.
To demonstrate the workings of .NET Reflector, I am going to load and examine the NUnitExample assembly already shown. Figure 7 shows this assembly loaded in .NET Reflector.
Figure 7** NUnitExample Assembly **
Inside of .NET Reflector there are various tools that you can use to examine this assembly further. To view the MSIL that makes up a method, click on the method and select Disassembler from the menu.
In addition to being able to view the MSIL, you can also view the method as C# by selecting Decompiler under the Tools menu. You could also view this method decompiled to Visual Basic .NET or Delphi by changing your selection under the Languages menu. Here is the code that .NET Reflector generated:
public void HashtableAddTest() { Hashtable hashtable1; hashtable1 = new Hashtable(); hashtable1.Add("Key1", "Value1"); hashtable1.Add("Key2", "Value2"); Assert.AreEqual("Value1", hashtable1["Key1"], "Wrong object returned!"); Assert.AreEqual("Value2", hashtable1["Key2"], "Wrong object returned!"); }
The previous code looks very much like the code I actually wrote for this method. Here is the actual code from this assembly:
public void HashtableAddTest() { Hashtable ht = new Hashtable(); ht.Add("Key1", "Value1"); ht.Add("Key2", "Value2"); Assert.AreEqual("Value1", ht["Key1"], "Wrong object returned!"); Assert.AreEqual("Value2", ht["Key2"], "Wrong object returned!"); }
Although there are some minor differences with the code, they are functionally identical.
While this example was a good way to show actual code versus decompiled code, it does not represent what I consider to be the best use of .NET Reflector, which is to examine .NET Framework assemblies and methods. The .NET Framework offers many different ways to perform similar operations. For example, if you need to read a set of data from XML, there are a variety of different ways to do this using XmlDocument, XPathNavigator, or XmlReader. By using .NET Reflector, you can see what Microsoft used when writing the ReadXml method of the DataSet, or what they did when reading data from the configuration files. .NET Reflector is also an excellent way to see the best practices for creating objects like HttpHandlers or configuration handlers because you get to see how the team at Microsoft actually built those objects in the Framework.
.NET Reflector was written by Lutz Roeder and can be downloaded from https://www.aisto.com/roeder/dotnet.
NDoc
Code documentation is almost always a dreaded task. I am not talking about the early design documents, or even the more detailed design documents; I am talking about documenting individual methods and properties on classes. The NDoc tool will automatically generate documentation for your code using reflection to examine the assembly and using the XML generated from your C# XML comments. XML comments are only available for C#, but there is a Visual Studio .NET Power Toy called VBCommenter which will do something similar for Visual Basic .NET. In addition, the next release of Visual Studio will support XML comments for more languages.
With NDoc you are technically still documenting your code, but you are documenting as you write it (in the XML comments), which is much easier to swallow. The first step when using NDoc is to turn on XML comments generation for your assembly. Right-click the project and select Properties | Configuration Properties | Build, then enter a path in which to save the XML file in the XML Documentation File option. When the project is built, an XML file will be created with all of the XML comments included. Here is a look at a method from the NUnit example documented with XML:
/// <summary> /// This test adds a number of values to the Hashtable collection /// and then retrieves those values and checks if they match. /// </summary> [Test] public void HashtableAddTest() { //Method Body Here }
The XML documentation on this method will be extracted and saved in the XML file, shown here:
<member name="M:NUnitExample.HashtableTest.HashtableAddTest"> <summary>This test adds a number of values to the Hashtable collection and then retrieves those values and checks if they match.</summary> </member>
NDoc uses reflection to look at your assembly, then reads the XML in this document, and matches them up. NDoc uses this data to create any number of different documentation formats, including HTML help files (CHMs). After generating the XML file, the next step is to load the assembly and the XML file into NDoc so they can be processed. This is done simply by opening NDoc and clicking the Add button.
Once the assembly and XML file are loaded into NDoc and after you customize the output using the range of properties available, clicking on the Generate button will start the process of generating the documentation. Using the default properties, NDoc generates some very attractive and functional .html and .chm files, thereby automating in a quick and efficient manner what would otherwise be a tedious task.
NDoc is an open source project and can be downloaded from https://ndoc.sourceforge.net.
NAnt
NAnt is a .NET-based build tool that, unlike the current version of Visual Studio .NET, makes it easy to create a build process for your project. When you have a large number of developers working on a single project, you can't rely on the build from a single user's box. You also do not want to have to build the project manually on a regular basis. Instead, you create an automated build process that runs every night. NAnt allows you to build your solution, copy files, run NUnit tests, send e-mail, and much more. Unfortunately, NAnt is lacking a nice looking graphical interface, but it does have a console application and XML files that specify which tasks should be completed during the build process. Note that MSBuild, the new build platform that's part of Visual Studio 2005, provides for very robust build scenarios and is similarly driven by XML-based project files.
NAnt in Action
In this example I am going to create an NAnt build file for the NUnitExample solution that I created earlier. First I need to create an XML file with the .build extension, place it in the root of my project, and then add an XML declaration to the top of the file. The first tag I need to add to the file is the project tag:
<?xml version="1.0"?> <project name="NUnit Example" default="build" basedir="."> <description>The NUnit Example Project</description> </project>
The project tag is also used to set the name of the project, the default target, and the base directory. The description tag is used to set a brief description of this project.
Next, I'll add the property tag, which can be used to store a setting in a single location that can then be accessed from anywhere in the file. In this case, I am going to create a property called debug, which I can then set to true or false, reflecting whether or not I want the project to be compiled in the debug configuration. (In the end, this particular property does not actually affect how the project will be built; it is simply a variable that you set and which will be read from later when you are actually determining how to build the project.)
Next, I need to create a target tag. A project can contain multiple targets which can be specified when NAnt is run. If no target is specified, the default is used, which I set in the project element. In this example, the default target is build. Let's take a look at the target element, which will contain the majority of the build info:
<target name="build" description="compiles the source code"> </target>
Inside the target element, I am going to set the name of the target to build and create a description of what this target will do. I'll also create a csc element, which is used to specify what should be passed to the csc C# compiler. Let's take a look at the csc element:
<csc target="library" output=".\bin\debug\NUnitExample.dll" debug="${debug}"> <references> <includes name="C:\program files\NUnit V2.1\bin\NUnit.Framework.dll"/> </references> <sources> <includes name="HashtableTest.cs"/> </sources> </csc>
First, I have to set the target of the csc element. In this case I will be creating a .dll file so I set the target to library. Next, I have to set the output of the csc element, which is where the .dll file will be created. Finally, I need to set the debug property, which determines whether the project will be compiled in debug. Since I created a property earlier to store this value, I can use the following string to access the value of that property: ${debug}. The csc element also contains a number of sub-elements. I need to create two elements: the references element will tell NAnt which assemblies I need to reference for this project, and the sources element will tell NAnt which files to include in the build. In this example, I reference the NUnit.Framework.dll assembly and include the HashtableTest.cs file. The complete build file is shown in Figure 8. (You would normally also create a clean target that would be used to delete the generated files, but I have omitted it for the sake of brevity.)
Figure 8 NAnt Build File
<?xml version="1.0"?> <project name="NUnit Example" default="build" basedir="."> <description>The NUnit Example Project</description> <property name="debug" value="true"/> <target name="build" description="compiles the source code"> <csc target="library" output=".\bin\debug\NUnitExample.dll" debug="${debug}"> <references> <includes name="C:\program files\NUnit V2.1\bin\NUnit.Framework.dll" /> </references> <sources> <includes name="HashtableTest.cs"/> </sources> </csc> </target> </project>
To build this file I need to go to the root directory of my project, where the build file is located, and execute nant.exe from that location. If the build is successful, you can find the .dll and .pdb file in the bin directory of this application. While using NAnt is definitely not as easy as clicking Build in Visual Studio, it is a very powerful tool for developing a build process that runs on an automated schedule. NAnt also includes helpful features such as the ability to run unit tests or copy additional files (features that are not supported by the current Visual Studio build process).
NAnt is an open source project and can be downloaded from https://sourceforge.net/projects/nant.
Switch Tools
I have lumped together two separate tools under the heading Switch Tools. These two tools are rather simple, but can be extremely useful. The first is the ASP.NET Version Switcher, which can be used to switch the version of ASP.NET that a virtual directory is running under. The second tool is the Visual Studio Converter, which can be used to switch a project file from Visual Studio .NET 2002 to Visual Studio .NET 2003.
When IIS handles a request, it looks at the extension of the file that is being requested, and then based on the extension mappings for that Web site or virtual directory, it either delegates the request to an ISAPI extension or handles it itself. This is how ASP.NET works; extension mappings are registered for all of the ASP.NET extensions and directs them to the aspnet_isapi.dll. This works flawlessly until you install ASP.NET 1.1, which upgrades the extension mapping to the new version of aspnet_isapi.dll. This causes errors when an application built on ASP.NET 1.0 tries to run with version 1.1. To fix this, you can switch all of the extension mappings back to the 1.0 version of aspnet_isapi.dll, but with 18 extension mappings it is not a lot of fun to do this by hand. This is where the ASP.NET Version Switcher becomes useful. This small utility can be used to switch the version of the .NET Framework that any single ASP.NET application is using.
Figure 9** ASP.NET Version Switcher **
Figure 9 shows the ASP.NET Version Switcher in action. Using it is as simple as selecting the application and then selecting the version of the .NET Framework that you would like the application to use. The tool then uses the aspnet_regiis.exe command-line tool to switch the application to the selected version of the Framework. This tool will become even more useful as future versions of ASP.NET and the .NET Framework are released.
ASP.NET Version Switcher was written by Denis Bauer and is available for download from https://www.denisbauer.com/NETTools/ASPNETVersionSwitcher.aspx.
The Visual Studio .NET Project Converter (see Figure 10) is very similar to the ASP.NET Version Switcher, except that it is used to switch the version of a Visual Studio project file. Even though there is only a small difference between versions 1.0 and 1.1 of the .NET Framework, once a project file from Visual Studio .NET 2002 is converted to Visual Studio .NET 2003, it cannot be converted back. While this might not be an issue most of the time (since there are few breaking changes between the .NET Framework versions 1.0 and 1.1), at some point you may need to switch a project back. This converter can convert any solution or project file from Visual Studio 7.1 (Visual Studio .NET 2003) to Visual Studio 7.0 (Visual Studio .NET 2002), and back if necessary.
Figure 10** Visual Studio .NET Project Converter **
The Visual Studio .NET Project Converter was written by Dacris Software. It is available for download from https://www.codeproject.com/macro/vsconvert.asp.
Conclusion
This has been a bit of a whirlwind tour of these tools, but I have tried to present you with at least enough information to whet your appetite. I trust that this article has provided you with some insight into a couple of free tools that you can start using right away to write better projects. I also urge you to make sure you have all the other right tools available to you, whether it is newest version of Visual Studio, a powerful computer, or a free utility. Having the right tools can make all the difference.
James Avery is a consultant working with .NET and other Microsoft technologies. He has written a number of books and articles, his most recent book being ASP.NET Setup and Configuration Pocket Reference (Microsoft Press, 2003). You can e-mail him at javery@infozerk.com and read his weblog at https://www.dotavery.com/blog.