Skip to content

Builder

The Builder pattern separates the construction of a complex object from its representation, enabling different configurations via a fluent interface. In Granit, this pattern manifests in the AddGranit*() extension methods that configure services module by module.

sequenceDiagram
    participant App as Program.cs
    participant Ext as AddGranitWolverine()
    participant Opts as WolverineMessagingOptions
    participant DI as IServiceCollection
    participant Val as ValidateOnStart

    App->>Ext: builder.AddGranitWolverine(configure?)
    Ext->>Opts: AddOptions().BindConfiguration("Wolverine")
    Ext->>Val: ValidateDataAnnotations().ValidateOnStart()
    Ext->>DI: AddScoped of ICurrentUserService
    Ext->>DI: AddSingleton of WolverineActivitySource
    opt configure provided
        Ext->>Opts: configure.Invoke(options)
    end
    Ext-->>App: IHostApplicationBuilder (fluent)

Each module exposes an AddGranit*() extension method:

ExtensionFileReceiver
AddGranit<TModule>()src/Granit.Core/Extensions/GranitHostBuilderExtensions.csIHostApplicationBuilder
AddGranitWolverine()src/Granit.Wolverine/Extensions/WolverineHostApplicationBuilderExtensions.csIHostApplicationBuilder
AddGranitBackgroundJobs()src/Granit.BackgroundJobs/Extensions/BackgroundJobsHostApplicationBuilderExtensions.csIHostApplicationBuilder
AddGranitFeatures()src/Granit.Features/ServiceCollectionExtensions.csIServiceCollection
AddGranitLocalization()src/Granit.Localization/Extensions/LocalizationServiceCollectionExtensions.csIServiceCollection

Audit note: the signatures are not yet symmetric across modules (see finding C2 in the critical dashboard). The target is the AddOptions<T>().BindConfiguration().ValidateOnStart() pattern.

The Builder allows each NuGet package to self-configure without the host application needing to know internal details. A single call replaces dozens of DI registration lines.

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
// One call per module -- fluent and composable
builder.AddGranit<MyAppHostModule>();
// Internally, the ModuleLoader calls AddGranitWolverine(),
// AddGranitPersistence(), AddGranitFeatures(), etc.
// in topological dependency order