Skip to main content
The Intent.ModuleBuilder module is a specialized Intent Architect module that enables you to design and build other Intent Architect modules using the visual designers.

Overview

Intent.ModuleBuilder provides:
  • Visual designer for module structure
  • Code generation for templates, decorators, and factory extensions
  • API model generation for strongly-typed metadata access
  • Designer configuration management
  • Module packaging and versioning

Installation

Install the Module Builder module in your application:
1
Via Intent Architect UI
2
  • Open your application in Intent Architect
  • Go to Modules section
  • Search for Intent.ModuleBuilder
  • Click Install
  • Run the Software Factory
  • 3
    Via Intent CLI
    4
    intent install-module Intent.ModuleBuilder
    intent run-software-factory
    

    Module Builder Designer

    The Module Builder designer is where you visually design your module’s structure.

    Designer Elements

    Intent Module

    Root element representing your module. Contains all templates, decorators, and configurations.

    File Template

    Defines a template that generates files. Supports T4, string interpolation, and custom file types.

    Template Decorator

    Modifies output from existing templates without changing the template source.

    Factory Extension

    Hooks into Software Factory lifecycle for custom logic execution.

    Static Content Template

    Outputs static files with optional keyword substitution.

    Module Settings

    Configurable settings that users can adjust in their applications.

    File Templates

    File Templates are the core building blocks for code generation.

    Template Types

    C# String Interpolation

    Recommended for new templates. Uses C# string interpolation for readable, maintainable templates:
    public override string TransformText()
    {
        return $@"
    using System;
    
    namespace {Namespace}
    {{
        public class {ClassName}
        {{
            {GetMembers()}
        }}
    }}";
    }
    
    private string GetMembers()
    {
        return string.Join("\n", Model.Properties.Select(p => 
            $"public {GetTypeName(p.Type)} {p.Name} {{ get; set; }}"));
    }
    

    T4 Templates

    Legacy approach using T4 (Text Template Transformation Toolkit):
    <#@ template language="C#" inherits="CSharpTemplateBase<ClassModel>" #>
    using System;
    
    namespace <#= Namespace #>
    {
        public class <#= ClassName #>
        {
    <#  foreach (var property in Model.Properties) { #>
            public <#= GetTypeName(property.Type) #> <#= property.Name #> { get; set; }
    <#  } #>
        }
    }
    

    Binary Files

    For images, PDFs, or other binary content:
    protected override CSharpFileConfig DefineFileConfig()
    {
        return new CSharpFileConfig(
            className: ClassName,
            @namespace: Namespace,
            relativeLocation: RelativeLocation)
        {
            FileExtension = "png"
        };
    }
    
    public override IBinaryFile GetBinaryFile()
    {
        var imageBytes = GetImageBytesFromResource();
        return new BinaryFile(GetMetadata().GetFilePath(), imageBytes);
    }
    

    Template Configuration

    Configure templates using stereotypes:
    File Extension: Output file extension (cs, ts, java, etc.)Output File Content:
    • Text-based - Regular text files supporting weaving
    • Binary - Binary files (images, PDFs)
    Templating Method:
    • C# String Interpolation - Modern, recommended
    • T4 Template - Legacy, for existing templates
    • Custom - Full control
    Default Location: Default output folderTemplate Output:
    • Single File - One file per instance
    • Multiple Files - Template can output multiple files
    Enabled By Default: Whether template is enabled on installation

    Template Registration Types

    Generates one file for each metadata element:
    public class EntityTemplateRegistration : FilePerModelTemplateRegistration<ClassModel>
    {
        public override string TemplateId => EntityTemplate.TemplateId;
    
        public override ITemplate CreateTemplateInstance(IOutputTarget outputTarget, ClassModel model)
        {
            return new EntityTemplate(outputTarget, model);
        }
    
        public override IEnumerable<ClassModel> GetModels(IApplication application)
        {
            return _metadataManager.Domain(application)
                .GetClassModels()
                .Where(x => x.HasStereotype("Entity"));
        }
    }
    

    API Models

    API models provide strongly-typed access to metadata from designers.

    Generating API Models

    1
    Reference the Designer
    2
    In Module Builder designer:
    3
  • Right-click your module
  • Add Designer Reference
  • Select the designer (e.g., Domain)
  • 4
    Create Element Model
    5
  • Right-click your module
  • New API Element Model
  • Configure:
    • Name: ClassModel
    • Element: Select designer element type
  • 6
    Run Software Factory
    7
    Generates API model classes in Api/ folder:
    8
    public class ClassModel : IMetadataModel
    {
        public string Id => _element.Id;
        public string Name => _element.Name;
        public IEnumerable<PropertyModel> Properties => /* ... */;
        
        public bool HasStereotype(string stereotypeName) => 
            _element.HasStereotype(stereotypeName);
    }
    

    Using API Models in Templates

    public class EntityTemplate : CSharpTemplateBase<ClassModel>
    {
        public EntityTemplate(IOutputTarget outputTarget, ClassModel model) 
            : base(TemplateId, outputTarget, model)
        {
        }
    
        public override string TransformText()
        {
            return $@"
    namespace {Namespace}
    {{
        public class {Model.Name}
        {{
            {GenerateProperties()}
        }}
    }}";
        }
    
        private string GenerateProperties()
        {
            return string.Join("\n        ", Model.Properties
                .Where(p => !p.HasStereotype("Ignore"))
                .Select(p => $"public {GetTypeName(p.Type)} {p.Name} {{ get; set; }}"));
        }
    }
    

    Static Content Templates

    For outputting static files with minimal customization:
    1
    Create Static Content Template
    2
  • Right-click module
  • New Static Content Template
  • Name it (e.g., DefaultConfigs)
  • 3
    Add Content Files
    4
    Place files in resources/ or content/ folder:
    5
    MyModule/
    └── resources/
        └── DefaultConfigs/
            ├── appsettings.json
            ├── .gitignore
            └── README.md
    
    6
    Configure Replacements
    7
    Optional keyword substitution:
    8
    public class DefaultConfigsTemplateRegistration 
        : StaticContentTemplateRegistration
    {
        public override IReadOnlyDictionary<string, string> Replacements => 
            new Dictionary<string, string> 
            {
                { "ProjectName", _application.Name },
                { "GeneratedDate", DateTime.Now.ToString("yyyy-MM-dd") },
                { "Author", "Your Company" }
            };
    }
    
    9
    Use in content files:
    10
    {
      "Application": {
        "Name": "<#= ProjectName #>",
        "GeneratedOn": "<#= GeneratedDate #>"
      }
    }
    

    Module Settings

    Provide configurable settings for module users:
    1
    Create Settings Configuration
    2
  • Right-click module
  • New Module Settings Configuration
  • Add Module Settings Field Configuration elements
  • 3
    Define Setting Fields
    4
    Configure each field:
    5
    // Generated settings extension class
    public static class ModuleSettingsExtensions
    {
        public static string ConnectionString(this IApplicationSettingsProvider settings)
        {
            return settings.GetSetting("MyModule.ConnectionString", "Server=localhost");
        }
    
        public static bool EnableLogging(this IApplicationSettingsProvider settings)
        {
            return settings.GetSetting("MyModule.EnableLogging", "true").ToBool();
        }
    }
    
    6
    Use in Templates
    7
    public override string TransformText()
    {
        var connectionString = ExecutionContext.Settings.ConnectionString();
        var loggingEnabled = ExecutionContext.Settings.EnableLogging();
        
        return $@"
    // Connection: {connectionString}
    // Logging: {loggingEnabled}
    ";
    }
    

    Module Dependencies

    Define dependencies on other modules:
    <dependencies>
      <dependency id="Intent.Common" version="3.7.0" />
      <dependency id="Intent.Common.CSharp" version="3.8.0" />
      <dependency id="Intent.OutputManager.RoslynWeaver" version="4.5.0" />
    </dependencies>
    
    Dependency version updates:
    • Always: Always update to specified version
    • If Newer: Update only if newer than installed
    • Never: Never automatically update

    Module Packaging

    1
    Build the Module
    2
    dotnet build --configuration Release
    
    3
    Create Package
    4
    intent package create
    
    5
    Or in Module Builder designer:
    6
  • Right-click module
  • Select Create Package
  • 7
    Package Output
    8
    Generates .imod file in bin/ folder:
    9
    MyModule/
    └── bin/
        └── Release/
            └── MyCompany.MyModule.1.0.0.imod
    

    Module Versioning

    Follow semantic versioning (MAJOR.MINOR.PATCH):
    • MAJOR: Breaking changes, incompatible API changes
    • MINOR: New features, backward compatible
    • PATCH: Bug fixes, backward compatible
    Version in .imodspec:
    <version>1.2.3</version>
    

    Best Practices

    Module Organization

    • Group related templates in folders
    • Keep API models separate from templates
    • Use consistent naming conventions
    • Document all public APIs

    Performance

    • Cache expensive computations in templates
    • Use lazy loading for metadata queries
    • Minimize Software Factory execution time
    • Profile large modules for bottlenecks

    Maintainability

    • Keep template logic simple and focused
    • Extract complex logic to helper classes
    • Write unit tests for API models
    • Version your modules appropriately

    Testing

    • Create test applications for each feature
    • Test upgrade scenarios
    • Verify backward compatibility
    • Test with various metadata configurations

    Module Builder Settings

    Configure Module Builder behavior:

    Create Partial API Models

    Generates partial classes for API models, allowing custom extensions:
    // Generated
    public partial class ClassModel { }
    
    // Your custom extensions
    public partial class ClassModel 
    {
        public bool IsAggregateRoot() => HasStereotype("Aggregate Root");
    }
    

    Dependency Version Overwrite Behavior

    Control how dependency versions are updated:
    • Always: Always update to template version
    • If Newer: Update only if newer
    • Never: Never update automatically

    Troubleshooting

    Check:
    • Template registration returns models in GetModels()
    • Template ID matches between template and registration
    • Designer references are correct
    • Output target is configured properly
    Verify:
    • Designer reference includes correct designer
    • Element type mapping is correct
    • Software Factory was run after changes
    • No generation errors in output log
    Check:
    • Module version is incremented
    • .imodspec supportedClientVersions includes your Intent version
    • Module is built in Release mode
    • Module cache is cleared

    Next Steps

    Creating Templates

    Detailed guide on template development

    Creating Decorators

    Learn to modify template outputs

    Factory Extensions

    Hook into Software Factory lifecycle

    Designer Configuration

    Create custom visual designers

    Build docs developers (and LLMs) love