Skip to main content
Intent Architect modules are built on a sophisticated architecture that enables code generation through a pipeline of components. This guide explains the core architectural patterns and components.

Module System Architecture

Module Package Structure

Modules are packaged as .imodspec files, which are XML-based manifests that define:
  • Module metadata (id, version, dependencies)
  • Templates to be registered
  • Factory extensions for lifecycle hooks
  • Metadata providers for designer integration
<?xml version="1.0" encoding="utf-8"?>
<package>
  <id>Intent.Common</id>
  <version>3.10.0</version>
  <supportedClientVersions>[4.6.0-a, 5.0.0-a)</supportedClientVersions>
  <summary>Base Implementation and Helper classes for modules.</summary>
  <templates />
  <dependencies></dependencies>
  <factoryExtensions>
    <factoryExtension id="Intent.Common.DecoratorExecutionHooks" />
    <factoryExtension id="Intent.Common.FileBuilderFactoryExtension" />
    <factoryExtension id="Intent.Common.TemplateLifeCycleHooks" />
  </factoryExtensions>
  <files>
    <file src="$outDir$/$id$.dll" />
    <file src="$outDir$/$id$.pdb" />
  </files>
</package>

Template Execution Pipeline

1

Template Registration

Templates are discovered and registered through TemplateRegistration classes. Each template gets a unique ID and is bound to metadata models.
Location: source/Modules/Intent.Modules.Common/Templates/IntentTemplateBase.cs:120
protected IntentTemplateBase(string templateId, IOutputTarget outputTarget)
{
    ExecutionContext = outputTarget.ExecutionContext;
    OutputTarget = outputTarget;
    Id = templateId;
    BindingContext = new TemplateBindingContext(this);
}
2

Decorator Injection

Decorators are added to templates to modify their behavior. Decorators are ordered by priority and executed in sequence.
Location: source/Modules/Intent.Modules.Common/Templates/IntentTemplateBase.cs:20-48
public abstract class IntentTemplateBase<TModel, TDecorator> : IntentTemplateBase<TModel>,
    IHasDecorators<TDecorator>
    where TDecorator : ITemplateDecorator
{
    private readonly List<TDecorator> _decorators = [];

    public IEnumerable<TDecorator> GetDecorators()
    {
        return _decorators.OrderBy(x => x.Priority);
    }

    public void AddDecorator(TDecorator decorator)
    {
        _decorators.Add(decorator);
    }
}
3

Template Configuration

Templates are configured through lifecycle hooks:
  • OnCreated() - Called after template creation
  • OnConfigured() - Called after all templates are configured
  • AfterTemplateRegistration() - Called after all templates are registered
4

Template Execution

Templates execute and generate output:
  • BeforeTemplateExecution() - Pre-execution hook
  • RunTemplate() - Generates the output
  • Type resolution and dependencies are tracked

Core Architectural Patterns

Base Template Classes

All templates inherit from IntentTemplateBase which provides:

Model Binding

Templates can be bound to metadata models from designers, enabling model-driven code generation.

Type Resolution

Built-in type resolution system for cross-template references and dependency tracking.

Output Targeting

Templates target specific output locations (projects, folders) through IOutputTarget.

Lifecycle Hooks

Multiple lifecycle hooks for initialization, configuration, and execution phases.

Decorator Pattern Implementation

Decorators extend template functionality without modifying the base template. They’re used for:
  • Adding cross-cutting concerns (logging, validation)
  • Injecting code into specific locations
  • Modifying template output
  • Adding dependencies and imports
Location: source/Modules/Intent.Modules.Common/Templates/DecoratorBase.cs:7-21
public class DecoratorBase : ITemplateDecorator, ISupportsConfiguration
{
    private const string PRIORITY = "Priority";

    public virtual void Configure(IDictionary<string, string> settings)
    {
        if (settings.ContainsKey(PRIORITY) && !string.IsNullOrWhiteSpace(settings[PRIORITY]))
        {
            this.Priority = int.Parse(settings[PRIORITY]);
        }
    }

    public int Priority { get; set; } = 0;
}
Decorators with lower priority values execute first. Default priority is 0.

Factory Extension Lifecycle

FactoryExtensionBase allows modules to hook into the Software Factory execution process:
Location: source/Modules/Intent.Modules.Common/Plugins/FactoryExtensionBase.cs:41-56
public abstract class FactoryExtensionBase : IExecutionLifeCycle, IFactoryExtension
{
    public abstract string Id { get; }
    public virtual int Order { get; set; }

    public virtual void Configure(IDictionary<string, string> settings)
    {
        if (settings.ContainsKey(nameof(Order)) && !string.IsNullOrWhiteSpace(settings[nameof(Order)]))
        {
            Order = int.Parse(settings[nameof(Order)]);
        }
    }
}
Available Lifecycle Hooks:
  1. OnStart - Software Factory initialization
  2. OnBeforeMetadataLoad - Before designer metadata is loaded
  3. OnAfterMetadataLoad - After metadata is available
  4. OnBeforeTemplateRegistrations - Before templates are registered
  5. OnAfterTemplateRegistrations - After all templates are registered
  6. OnBeforeTemplateExecution - Before templates execute
  7. OnAfterTemplateExecution - After templates have run
  8. OnBeforeCommitChanges - Before changes are written to disk
  9. OnAfterCommitChanges - After all changes are committed

Metadata Provider System

Metadata providers expose designer models to templates through strongly-typed APIs:
1

Model Definition

Models are defined in Intent Architect designers (Domain Designer, Services Designer, etc.)
2

API Generation

The Module Builder generates strongly-typed API classes from the designer metadata
3

Template Consumption

Templates receive models through their constructor and use them to drive code generation
Always use the generated API classes to access metadata. Direct metadata access bypasses type safety and may break with designer changes.

Type Resolution and Dependencies

The type resolution system enables templates to reference types from other templates:
Location: source/Modules/Intent.Modules.Common/Templates/IntentTemplateBase.cs:362-390
public virtual ClassTypeSource AddTypeSource(string templateId, string? collectionFormat)
{
    var typeSource = ClassTypeSource.Create(ExecutionContext, templateId, CreateCollectionFormatter)
        .WithNullableFormatter(Types.DefaultNullableFormatter);

    if (!string.IsNullOrWhiteSpace(collectionFormat))
    {
        typeSource = typeSource.WithCollectionFormatter(CreateCollectionFormatter(collectionFormat));
    }

    Types.AddTypeSource(typeSource);
    return typeSource;
}
Key Concepts:
  • Type Sources: Templates register themselves as type sources for others to discover
  • Dependency Tracking: When a template resolves a type from another template, a dependency is automatically created
  • Collection Formatters: Control how collection types are formatted (e.g., List<T>, T[], IEnumerable<T>)

Learn More

Deep dive into the type resolution system and how to use GetTypeName() methods

Software Factory Execution Context

The ISoftwareFactoryExecutionContext provides access to application-wide services:
  • File system operations
  • Template discovery and lookup
  • Event bus for inter-module communication
  • Configuration and settings
  • Logging infrastructure
Location: source/Modules/Intent.Modules.Common/Templates/IntentTemplateBase.cs:150-154
public ISoftwareFactoryExecutionContext ExecutionContext { get; }
public IOutputTarget OutputTarget { get; }
public ITemplateBindingContext BindingContext { get; }
public IFileMetadata FileMetadata { get; private set; }

Next Steps

Quick Start

Build your first module in under 10 minutes

Template Development

Learn how to create templates

Decorator Development

Extend templates with decorators

Factory Extensions

Hook into the execution lifecycle