I am a big fan of the DRY principle. This means that whenever I can do something that can be reused with minimal or no effort, I try to do it. Recently I’ve started developing a REST framework for our projects, which is not based on WCF (will blog about this too). One of the most problematic areas is how to create service proxies easily without having to duplicate loads of code, but at the same time maintain maximum flexibility. After going through several options, the most attractive is creating a Visual Studio custom code generator.
Since there are almost no resources (and the existing ones are very blurry) I’ve decided to create a series of blogs that will be a guide to creating custom code generators, followed by some other posts with real examples and solutions to problems.
The series is divided into four parts:
Part I (this one) – creating a Visual Studio Package
Part II – creating and registering a code generator
Part III – generating code & debugging
Part IV – creating the setup project and deploying the package
*DISCLAIMER* – Even if everybody is in the new VS2010 hype, I still think there are a lot of developers that are and will be working in VS2008 for a while.
Before jumping to the gory details, you need to be aware that creating code generators is only possible using Visual Studio Professional or higher. Also, you need to install the Visual Studio SDK which can be found here.
Part I – Creating a Visual Studio package
In order to create a custom code generator we need to create a Visual Studio package. I am not 100% sure that this is needed, but I wasn’t able to install the code generator in any other kind of project.
So open Visual Studio and create a new Visual Studio Integration Package project. I’ll call it MyCodeGenerator
A wizard will start guiding you through the package creation steps. You will want to select Visual C# as the language, and to create a new key to sign the assembly. Optionally, if you already have a key, use that one:
The next screen will ask you for package details. You can enter here a company name, a human-readable package name, the package version and the minimum required Visual Studio version required to use the package. Also, you can set an icon for the package. This information will be later used for signing the package.
The third screen will allow you to add extra functionality to the package (menu commands, tool windows or a custom editor). For our generator we don’t need any, so leave the fields unchecked.
To keep things simple, we won’t use integration or unit tests, so leave the next fields unchecked. If you are using TDD with the Visual Studio test framework, you can leave the checkboxes selected.
After clicking finish, you will get a new Visual Studio Integration Project.
Package and assembly registration
Add a new class, and name it MyGenerator.cs. Change the class visibility to public. Since Visual Studio code generators and packages are used as COM objects, we need to register the generator assembly and package. The Visual Studio SDK contains an attribute class that makes this an easy task. The class is called CodeGeneratorRegistrationAttribute and you can find it in the SimpleFileGenerator example project (mine is in c:Program FilesMicrosoft Visual Studio 2008 SDKVisualStudioIntegrationSamplesProjectCSharpExample.SingleFileGeneratorCodeGeneratorRegistrationAttribute.cs). Alternatively, you can use the one in the attached project.
Add the file to the project and add references to the following assemblies:
The VSLangProj assemblies are duplicated in the GAC (they can be found in two locations). I have successfully used the ones in the C:Program FilesMicrosoft Visual Studio 9.0Common7IDEPublicAssemblies folder.
Also, you need to register the assembly from COM Interop. You can accomplish this by opening the project properties and checking the Register for COM interop checkbox.
That’s it for the first step.
Check out the second part of this tutorial on how the code generator is implemented and how we can debug it.