[Source: http://geekswithblogs.net/EltonStoneman]

The basic Code Generation Guidance Package on CodePlex comes with an additional sample Guidance package. This sample is intended to demonstrate how the functionality of the base package can be customised to create a project-specific Guidance package, where you can easily add tailored code generation recipes to your package. In the basic package are the Wizard steps necessary to configure ad-hoc code generation, but there are also ValueProviders which can read configuration from recipes without requiring the whole user interface.

Installation

You’ll need to modify the hard-coded paths and URIs in the sample package, so it doesn’t come with an installed release. If you open the Sixeyed.Guidance.CodeGenerationSample solution you’ll see that it references the base Sixeyed.Guidance.CodeGeneration and Sixeyed.CodeGeneration assemblies. The sample contains a set of T4 templates in the \Templates\Text directory, the XML configuration for the package and the XML includes for individual recipes. There’s no additional code in the sample project, all the required functionality is in the referenced base package.

Together with the GAX project, there’s a database project which you can use to create a SQL Server database suitable for the data-bound recipes to run against. To install, run the CreateDatabase script and then execute the SSIS package to populate data from the included Excel workbook (this is only necessary if you want to run the recipes as-is, otherwise you can modify the XML to use your own database).

Sample T4 Templates

There are T4 templates for each of the metadata providers in the base package. The scripts named _Simple.tt are straightforward and begin with the name of the expected provider; to run them, you can use Add Generated Items from the base package, select the relevant metadata and point to the template. To demonstrate more useful code generation, there are two more substantial templates:

  • ConfigurationSection.cs.tt – use the File source and the Text provider on this template. If you select Configuration.txt (from the database project) as the source, the recipe will generate a typed configuration class, which has a static property to access the current config settings. The template can be easily extended to add a Default value for optional settings, and the same text file can be used to drive a different T4 template to generate the actual configuration settings;
  • StoredProcedure.cs.tt – use the SQL Server database source and the Stored Procedure provider. Select a procedure and the recipe will generate a DAL class to execute the stored procedure. This class won’t compile, as it inherits from a base class which isn’t provided, but it demonstrates one approach for DAL generation.

Sample Recipes

The included recipes demonstrate configuring one or more settings for code generation so that the Wizard can be tailored or avoided altogether. Generate Stored Procedure shows this best, configuring the metadata provider using the SourceConfigurationValueProvider:

<Argument Name=SourceConfiguration Type=Sixeyed.CodeGeneration.Metadata.SourceConfiguration, Sixeyed.CodeGeneration>

<ValueProvider Type=SourceConfigurationValueProvider

SourceTypeName=Database

SourceName=SqlServer Database

SourceUri=Data Source=x\y;Integrated Security=True;Initial Catalog=Scratchpad;

ProviderName=Stored Procedure Provider>

</ValueProvider>

</Argument>

These settings are the equivalent of the first Wizard page, selecting the metadata source. It specifies the source type and source name, the URI for the source (in this case, the Scratchpad database included with the sample), and the metadata provider name. Having the SourceConfiguration argument pre-populated means the first Wizard page will be skipped. The recipe also specifies the T4 template to use with the TemplateConfigurationValueProvider:

<Argument Name=TemplateConfiguration Type=Sixeyed.CodeGeneration.Generation.TemplateConfiguration, Sixeyed.CodeGeneration>

<ValueProvider Type=TemplateConfigurationValueProvider

TemplatePath=x:\y\z\Templates\Text\StoredProcedure.cs.tt>

</ValueProvider>

</Argument>

Only the template path is specified here, but other settings (target namespace, class name etc.) can also be provided. Having the TemplateConfiguration argument populated means the third Wizard page will not be shown. Running this recipe gives you a Wizard form which only contains the second page, for selecting metadata items, pre-populated with the list which has already been loaded from the configured database:

– note that the other pages are not available, so the user is constrained to using the configured source and T4 template.

Other recipes demonstrate configuring all or part of the settings needed for code generation. Generate Simple runs a template which requires no metadata, so it connects to the metadata source, runs the template and adds the project output with no user intervention. Additional Source demonstrates how you can extend the base code generation guidance package with additional metadata sources and providers of your own, without rebuilding the base package. Specify the SourceAssemblyConfiguration argument:

<Argument Name=SourceAssemblyConfiguration Type=Sixeyed.CodeGeneration.Metadata.SourceAssemblyConfiguration, Sixeyed.CodeGeneration>

<ValueProvider Type=SourceAssemblyConfigurationValueProvider

AssemblyList=Sixeyed.CodeGeneration.Tests>

</ValueProvider>

</Argument>

– and the .NET assemblies named in AssemblyList (semi-colon separated) will be interrogated at run-time to identify IMetadataSource and IMetadataProvider implementations (there’ll be more detail on those interfaces in a coming post). Any available classes will be added to the list of sources and providers shown in Add Generated Items, and can also be used in SourceConfiguration argument values.

Usage

By providing custom recipes, you can tailor your own Guidance packages which contain recipes for generating classes or other artifacts based on established patterns. This gives the project team an easy way of ensuring consistency for common coding problems in the domain – configuration sections and stored procedure wrappers are simple examples. Note that the URIs and paths are hard-coded. The code generation guidance package will attempt to find a T4 template if the path is not fully stated, but it won’t always succeed (there’s an issue with returning the running GuidancePackage instance that I haven’t tracked down). In a typical project though, templates would be in SCM and source URIs would be consistent among developers, so fully-qualified hard-coded text shouldn’t be a problem.

I’ll be extending the sample package to include other templates that may be useful starting points for common code generation tasks – enums to represent reference data, unit tests for .NET and BizTalk artifacts, MSBuild scripts and anything else that occurs. If you have any templates of your own which would fit in a standard library, let me know and I’ll add you as a CodePlex contributor.