Skip to main content

Overview

ITemplateDecorator is the base interface for all template decorators in Intent Architect. Decorators allow you to extend and modify template behavior without changing the template source code itself. Decorators are applied to templates that implement IHasDecorators<TDecorator> and are executed during template generation to add functionality, modify output, or provide additional context.

ITemplateDecorator Interface

namespace Intent.Templates
{
    public interface ITemplateDecorator
    {
        int Priority { get; }
    }
}
Priority
int
Controls the execution order of decorators. Decorators with lower priority values execute first. Default is 0.

DecoratorBase

The DecoratorBase class provides a convenient base implementation of ITemplateDecorator with configuration support.
namespace Intent.Modules.Common.Templates
{
    public class DecoratorBase : ITemplateDecorator, ISupportsConfiguration
    {
        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;
    }
}

Properties

Priority
int
default:"0"
The execution priority of the decorator. Lower values execute first.

Methods

Configure
void
Configures the decorator with settings from the module configuration.
settings
IDictionary<string, string>
Configuration settings for the decorator, including optional Priority setting.

Creating Custom Decorators

To create a custom decorator, inherit from DecoratorBase and define your decorator-specific properties and methods.

Basic Example

using Intent.Engine;
using Intent.Modules.Common.Templates;

public interface IExampleDecorator : ITemplateDecorator
{
    string GetAdditionalContent();
}

public class ExampleDecorator : DecoratorBase, IExampleDecorator
{
    public const string DecoratorId = "MyModule.ExampleDecorator";
    
    private readonly IExampleTemplate _template;
    private readonly IApplication _application;

    public ExampleDecorator(IExampleTemplate template, IApplication application)
    {
        _template = template;
        _application = application;
        Priority = 10;
    }

    public string GetAdditionalContent()
    {
        return "// Additional decorator content";
    }
}

Using Decorators in Templates

public class MyTemplate : CSharpTemplateBase<IClass>, 
    IHasDecorators<IExampleDecorator>
{
    private readonly DecoratorDispatcher<IExampleDecorator> _decorators;

    public MyTemplate(IOutputTarget outputTarget, IClass model) 
        : base("MyTemplate", outputTarget, model)
    {
        _decorators = new DecoratorDispatcher<IExampleDecorator>(
            () => GetDecorators());
    }

    public IEnumerable<IExampleDecorator> GetDecorators()
    {
        return ExecutionContext.Decorators
            .OfType<IExampleDecorator>()
            .Where(x => x.Template == this)
            .OrderBy(x => x.Priority);
    }

    public override string TransformText()
    {
        var decoratorContent = _decorators.Dispatch(d => d.GetAdditionalContent());
        
        return $@"
namespace {Namespace}
{{
    public class {ClassName}
    {{
        {decoratorContent}
    }}
}}
";
    }
}

Decorator Registration

Decorators are registered using DecoratorRegistration<TTemplate, TDecoratorContract>.
using Intent.Engine;
using Intent.Modules.Common.Registrations;

public class ExampleDecoratorRegistration : 
    DecoratorRegistration<IExampleTemplate, IExampleDecorator>
{
    public override string DecoratorId => ExampleDecorator.DecoratorId;

    public override IExampleDecorator CreateDecoratorInstance(
        IExampleTemplate template, 
        IApplication application)
    {
        return new ExampleDecorator(template, application);
    }
}
The Software Factory automatically discovers and registers decorator registrations through assembly scanning.

Best Practices

Use Unique IDs

Always use unique decorator IDs following the pattern ModuleName.DecoratorName

Set Appropriate Priority

Use priority to control execution order when decorators depend on each other

Keep Decorators Focused

Each decorator should have a single, well-defined purpose

Test Decorator Ordering

Verify decorator execution order when multiple decorators apply to the same template

Build docs developers (and LLMs) love