Using a CodeSmith Project inside Visual Studio

Introduction

The tight integration with Visual Studio allows you to fully manage any CodeSmith Project right from Visual Studio!  This means you can maintain a high Code Generation presence right within Visual Studio and not have to switch applications to run code generation. 

Managing a CodeSmith Project From Visual Studio

To manage a CodeSmith Project, you can use the Right-Click context menu of a CodeSmith Project file from the Solution Explorer window. 

(Depicted on the right)

The menu options include:

  1. Generate Outputs - Will kick off the generation process to produce outputs configured in your CodeSmith Project.
  2. Manage Outputs - Gives the ability to manage your CodeSmith Project.
  3. Add Outputs
  4. Output Options - (Depicted below) Only available in Visual Studio, and allows you to control the output options after generation.
    IMAGE GOES HERE
    1. Add Outputs To Project - Will take any outputs from your CodeSmith Project and include them in your Visual Studio project.
    2. Hide Outputs - Will take any outputs of your CodeSmith Project and make them child nodes, dependant on your CodeSmith Project file (shown below).  Hidden nodes can be collapsed, and since much of the time generated code shoudln't be touched, it's a great way to hide the temptation of other developers attempting to modify the generated code.
    3. Generate On Build - A menu driven way to have your templates use Active Generation.  You can also specify the BuildAction value in the property sheet of your CodeSmith Project. (more below)
Active Generation

You can use ActiveGeneration quite easily in your Visual Studio projects now, simply by specifying the BuildAction of your CodeSmith Project.

Setting the BuildAction = "Generate" in the properties of you CodeSmith Project file in the Solution Explorer will cause your entire generation process to occur prior to your project building.  This means that any Outputs that you have in your CodeSmith Project will be generated  and if you want, included in the Visual Studio project.

Example:
We have a BusinessObject.csp CodeSmith Project in our class library Visual Studio project. This CSP has 4 outputs, that generate from the same BusinessObject.cst CodeSmith template.

  • Order.cs
  • Product.cs
  • Profile.cs
  • Supplier.cs

Looking into the properties of the CodeSmith Project, you can view the Build Action of the file, and there is an option to set it to Generate on Build. Meaning every time you need to tweak your Database meta-data, XML Property meta-data, or CodeSmith template, the changes are picked up in your Visual Studio project the very next time you build.

This enables you to alleviate much of the frequent developer problems with making changes across all of your classes, during the development process.

Output Window Generation Feedback

As you can see depicted in the image below, the business object was generated, and then the build process began.  This is a very powerful feature since it allows you to have strong Code Generation integration inside all of your projects in Visual Studio without having to switch to CodeSmith Studio or Explorer.

Adding Files to Visual Studio Using DependentUpon Hierarchy

CodeSmith 5.0 added a new overload to the templates RenderToFile that will take a parent (DependentUpon) file. This will add metadata to the output file that Visual Studio will use when adding the file to create the hierarchy.

To get your template to support this, you'll need to update the template to use the RenderToFile overload that takes a parent file.  Next, add the CodeSmith Project to the Visual Studio project and Generate Outputs. CodeSmith will automaticly add the outputs to your Visual Studio project creating the hierarchy.

Sample Template Code

//Create Sub template using the Create method to automaticly wire everything up
EntityGeneratedClass entityClass = this.Create<EntityGeneratedClass>();
EntityEditableClass partialClass = this.Create<EntityEditableClass>();

string className = type.Name;

string parentFileName = className + ".cs";
parentFileName = Path.Combine(OutputDirectory, parentFileName);
//Output parent file
partialClass.RenderToFile(parentFileName, false);

string fileName = className + ".Generated.cs";
fileName = Path.Combine(OutputDirectory, fileName);
//Output child (dependent) file linking to parent
entityClass.RenderToFile(fileName, parentFileName, true);