Fulcrum Toolkit Developer Quick Start

Overview

This document is intended to outline what developers need to do write a Fulcrum plugin. This document will take more about high level work items, rather than about specific interfaces and steps because those things may change during Fulcrum’s lifetime – especially in early versions.

Code Generation Basics

Before we start lets review the basics of code generation. Mulitple flavors of code generation exist, but we’ll focus on the style employed by Fulcrum which is template code generation.

Some term delimitations are:

How To Write A Fulcrum Plugin

A Fulcrum plugin serves 2 purposes – inform the engine about settings (template file, output directory, etc…) and provides data for the template to work against.

The FulcrumWeakEventManager is a simple plugin which serves the purpose of being a sample. Study it and follow its example while writing your plugin.

The first step in creating a plugin is to create a new VS project. Do all the grunt stuff to setup the namespace you desire, build settings, references, etc…. It is recommended you look at the other plugin projects to see what they do, and do something similar.

Next you need to create your entry point class. This is a class which derives from GenerationUnit inside the Fulcrum assembly. The recommended name is XxxxGenerationUnit where Xxxx is the name of the plugin. You need to mark it with the Export attribute so Fulcrum can find it at run-time. Implement the appropriate virtual methods. See the GenerationUnit class for documentation, and the sample for an example of a likely implementation. There are 4 key things you need to know about GenerationUnit:
The Settings object is next. This class implements the ISettings interface, and the recommended name ix XxxxSettings. The class should provide get/set properties for settings to pass into the GenerationUnit. Using the SettingsAttribute you can expose these settings to the FulcrumConsole command line interface. Simply slap the attribute onto the appropriate properties, and initialize the attribute with the desired values. At run-time the FulcrumConsole will parse the command line and call the setters as appropriate.

Lastly implement your DataContext class or classes. If you only have one then XxxxDataContext is the recommended name. The DataContext class must inherit from GenerationDataContext. Implement the appropriate methods/properties – the most key being TemplateFile which is the name of the template file to use with the data context. Extend the class with additional properties which contain the metadata your template file will need.

How To Write a Template

Fulcrum is build upon the T4 code generation technology inside Visual Studio. The template files consist of text which makes up the generated code, along with metalogic declared within special tags.

The metalogic can be any .NET language, which may be significantly different from the language of the generated code.

T4 syntax plugins exist for Visual Studio. Finding them by searching the Internet should be trivial. These will help with the editing process. Also on-line is documentation about T4 syntax and behavior.

The metadata will be passed in via the GenerationDataContext.CurrentDataContext static property. This value can be cast to the type specified in the plugin, in order to access additional members not present in the base class.

Like the plugin code, the best way to learn is to look at the sample project’s template file.

Unit Testing

Code generation is a great multiplier. It allows a developer to be more productive. But if the code generation process has a bug, the effects of that bug can also be multiplied. One way to ensure the quality of the generated code is by unit testing.

Generating the unit test code smacks of circular reasoning. Handwritten unit tests for the generated code negates the benefits of generating the code in the first place.

The alternative is to unit test the metadata, metalogic and template.

The metadata can be hard to unit test, especially if the metadata is handwritten. “Unit testing” the metadata can often only be done via code review. However one can unit test the code which loads the metadata from whatever store holds it.
The metalogic can be unit tested, provided it is in a regular assembly. Metalogic embedded in the template is difficult, if not impossible, to unit test. Therefore put as much metalogic as possible into the Fulcrum plugin, and simply call it from the template. Not only does this enable unit testing, but it reduces template complexity and makes it easier to build multiple templates (say for different output languages) for the same metadata.

The template can only be tested by generating code with sample metadata, and then unit testing the resulting code.
Fulcrum plugin writers are encouraged to follow this unit testing strategy to ensure quality of their generated code.

Putting It All Together

Now that we gone through each step individually, lets walk through how this happens at run-time.