Creating a BuildAssembler Build Component

This topic will walk you through the creation of a build component project.

Defining the Build Component Configuration

The first step is to determine what items will appear in the build component configuration. The configuration is stored as an XML fragment in the help file builder project file. The root node is always component. Define your own elements to contain the build component configuration that will be nested within the root element. It is possible that a build component will have no configurable elements. In that case, there is nothing to add to the default configuration. Below is an example of a configuration that is passed to a build component.

Example Build Component Configuration
<component id="Copy From Index Component">
  <index name="reflection" value="/reflection/apis/api" key="@id" cache="15">
    <data base="{@FrameworkReflectionDataFolder}" recurse="true" files="*.xml"
      duplicateWarning="false" />
    <data files="reflection.xml" />
  </index>
  <copy name="reflection" source="*" target="/document/reference" />
</component>

Creating the Project

This section describes how to create and configure the build component project. It will describe the process for a C# project but the steps should be fairly similar for a VB.NET project with a few differences in the configuration option titles.

Create the Build Component Project

  1. In Visual Studio, select the New Project option. In the New Project dialog box, select the C# or VB.NET language, and then select the Documentation subcategory. Select the BuildAssembler Build Component template, give it a name and click OK to create it. Once it has been created, right click on the project and select Properties.

  2. In the Application tab, set the assembly name and default namespace as you see fit.

  3. In the Package tab, set the NuGet package properties.

  4. By default, the Debug project properties are set to use the standalone GUI for debugging which will help you see if the component can be located, that the configuration form is working if you created one for the component, and that it is working within the build as expected. See the Debugging Components and Plug-Ins for some special requirements when debugging components and plug-ins.

      Tip

    Using the standalone GUI as the host is easier than using Visual Studio as the package locks the assemblies once the help file builder project has loaded them for use and you will not be able to rebuild them. Shutting down the standalone GUI frees the assemblies so that you can rebuild them and start a new debugging session.

    In the help file builder project that you use to test your build component, set the project's Component Path property to the folder containing your build component's assembly. If you have opened the project's Components property page before setting the component path, you may need to close and reopen the project in order for it to discover your build component assembly.

  5. Optionally, select the Signing tab and check the "Sign the assembly" checkbox. Select "<New...>" from the "Choose a strong name key file" dropdown, enter a filename, and click OK to create the key file. You can protect the key file with a password if you like or uncheck the option to create one without a password.

You are now ready to edit the build component class itself. See the comments in the template class for information on how to get started. Some general information is given below. Note that multiple build components can reside within the same assembly. Add new class files to the project and implement the necessary methods as described below and as shown in the template class.

The build component is derived from the Sandcastle.Core.BuildAssembler.BuildComponent.BuildComponentCore class and consists of a few methods that you must implement along with a nested Managed Extensibility Framework (MEF) factory class that describes the component, creates instances, and allows interaction with the design tools and build engine. These are described below. Review the code for "TODO:" comments to find sections that need attention such as setting the build component's ID, the configuration file insertion points, the default configuration, etc. If you followed the steps in the Creating the Project section, you can run the project and debug it by setting breakpoints in the build component's code. As noted above, set the test project's Component Path property to the folder containing the build component assembly first. If necessary, close and reopen the test project so that it can discover the build component.

The Export Attribute Metadata

The nested factory class is a MEF component. The BuildComponentExportAttribute is used to define the necessary metadata that enables the help file builder to load and use the component.

Id

The Id parameter is required and is used to uniquely identify the build component.

Version

The Version property is optional and allows you to define the build component version displayed in the help file builder property page when the build component is selected.

Copyright

The Copyright property is optional and allows you to define the build component copyright displayed in the help file builder property page when the build component is selected.

Description

The Description property is optional and allows you to define the build component description displayed in the help file builder property page when the build component is selected.

IsVisible

The IsVisible property is optional and allows you to define whether or not the build component should be visible in the help file builder's property page. The default if omitted is false and the build component will not show up in the list of build components that can be added to the project. It will only be included in a project if referenced as a dependency in another build component.

The Factory Class

The factory class is derived from Sandcastle.Core.BuildAssembler.BuildComponent.BuildComponentFactory and contains the following properties and methods.

Constructor

In the constructor, set the ReferenceBuildPlacement and ConceptualBuildPlacement properties which describe how to place the component in the BuildAssembler configuration file. Each uses a ComponentPlacement instance to describe how they component should be inserted. Placement is defined using a required placement action value, a required component ID, and an optional component instance value. If a component is not usable in either a reference or conceptual build, the corresponding property can be omitted.

  • The PlacementAction parameter defines where to insert the configuration relative to the indicated component ID where relevant. It can have one of the following values:

    • Start - The configuration is inserted at the start of the configuration file ahead of all others. If multiple build components use this option they are all inserted at the start in no particular order. The component ID is ignored with this option.

    • End - The configuration is inserted at the end of the configuration file after all others. If multiple build components use this option they are all inserted at the end in no particular order. The component ID is ignored with this option.

    • Before - The configuration is inserted before the component indicated by the required ID and optional instance parameters.

    • After - The configuration is inserted after the component indicated by the required ID and optional instance parameters.

    • Replace - The configuration for the custom component replaces an existing component indicated by the required ID and optional instance parameters.

      Note

    If a component already exists in the configuration file with a matching ID attribute it is assumed to be the same component in the correct location and is automatically replaced with the custom configuration.

  • The ID parameter can be used to identify another component in the configuration file by ID.

  • The instance parameter can be used to identify a specific instance of a build component in the configuration file. For example, the Copy From Index component appears multiple times in the standard configuration file. If you need to merge a custom build component before or after one of these occurrences or replace one, you can use this attribute to specify which one. If omitted, the first instance is assumed.

Dependencies

Override this property to specify an enumerable list of component IDs on which the current component depends. If the indicated components do not exist in the project settings or in the configuration file template already, they will be added automatically with their default configuration at build time. This property does not need to be overridden if there are no dependencies. Dependent configurations are merged prior to project settings. As such, it is not required that a dependent component appear in the project as well. If it does, the project settings will override the default configuration.

DefaultConfiguration

Override this property to specify the default configuration for a custom build component. This information is used when the component is added as a dependency and when the component is added to the project and the user does not modify it. You can use the various replacement tags as attribute values. These will be replaced at build time with the appropriate project values. The default if not overridden is an empty string.

Create

This method must be implemented to create an instance of the build component. Simply create the component instance and return it.

The Build Component Template Class

In its simplest form, the only two methods you need to implement are the Initialize and Apply methods. A few supporting properties and methods in the base class are also available for use.

Initialize

This method is implemented to initialize the component. It is passed an XML navigator that contains the configuration information.

Apply

This method is implemented to apply the component's changes to the document. It is passed an XML document containing the current document and a key that identifies it (the API member in reference builds or the topic ID in conceptual builds.

WriteMessage

This method is used to output a message from the component. The message level parameter indicates the severity of the message. If Error is used, it will stop the build. An overload is supplied to which you can pass the key. This can help associate a message with a particular topic or member ID to make the problem easier to find and fix.

OnComponentEvent

This method is used to invoke the ComponentEvent event on the BuildAssembler instance. This is a way to communicate information between components. To use it, the receiving component attaches an event handler to the BuildAssembler.ComponentEvent event. The sending component invokes this method and passes an event argument instance containing any data relevant to the event. It is up to the receiving event handler to cast the event argument parameter to a particular type that it is interested in to see if it should handle the event.

See Also