Skip to content

Module Auto-Discovery ​

The Module Auto-Discovery generator scans all referenced assemblies for IModuleRegistration implementations and produces AddAllModules() and MapAllModuleEndpoints() extension methods. This eliminates the need for a manually maintained ModuleRegistration.cs file in the host project.

What It Replaces ​

Previously, adding a module required updating the host's composition root:

csharp
// Old approach -- manual ModuleRegistration.cs
public static class ModuleRegistration
{
    public static IServiceCollection AddModules(
        IServiceCollection services, IConfiguration configuration)
    {
        CatalogModule.ConfigureServices(services, configuration);
        OrderingModule.ConfigureServices(services, configuration);
        // Must manually add each new module here
        return services;
    }

    public static WebApplication MapModuleEndpoints(this WebApplication app)
    {
        CatalogModule.ConfigureEndpoints(app);
        OrderingModule.ConfigureEndpoints(app);
        // Must manually add each new module here
        return app;
    }
}

The source generator replaces this entirely:

csharp
// New approach -- source-generated
builder.Services.AddAllModules(builder.Configuration);
app.MapAllModuleEndpoints();

How It Works ​

  1. The generator runs in the host project (e.g., EShop.WebApi)
  2. It scans all referenced assembly symbols for types implementing IModuleRegistration
  3. It verifies each type has both static methods: ConfigureServices() and ConfigureEndpoints()
  4. It generates a GeneratedModuleRegistration class that calls each module in order

What Gets Generated ​

csharp
public static class GeneratedModuleRegistration
{
    public static IServiceCollection AddAllModules(
        this IServiceCollection services, IConfiguration configuration)
    {
        CatalogModule.ConfigureServices(services, configuration);
        OrderingModule.ConfigureServices(services, configuration);
        return services;
    }

    public static IEndpointRouteBuilder MapAllModuleEndpoints(
        this IEndpointRouteBuilder app)
    {
        CatalogModule.ConfigureEndpoints(app);
        OrderingModule.ConfigureEndpoints(app);
        return app;
    }
}

Module Ordering ​

By default, modules are registered in alphabetical order by fully qualified type name. Control the order with the [ModuleOrder] attribute:

csharp
using Modulus.Mediator.Abstractions;

[ModuleOrder(1)]
public class CatalogModule : IModuleRegistration
{
    public static IServiceCollection ConfigureServices(
        IServiceCollection services, IConfiguration configuration) { /* ... */ }

    public static IEndpointRouteBuilder ConfigureEndpoints(
        IEndpointRouteBuilder app) { /* ... */ }
}

[ModuleOrder(2)]
public class OrderingModule : IModuleRegistration
{
    public static IServiceCollection ConfigureServices(
        IServiceCollection services, IConfiguration configuration) { /* ... */ }

    public static IEndpointRouteBuilder ConfigureEndpoints(
        IEndpointRouteBuilder app) { /* ... */ }
}

Lower values execute first. Modules with equal order values are sorted alphabetically.

Usage in Program.cs ​

csharp
var builder = WebApplication.CreateBuilder(args);

// Register all module services (source-generated)
builder.Services.AddAllModules(builder.Configuration);

var app = builder.Build();

// Map all module endpoints (source-generated)
app.MapAllModuleEndpoints();

app.Run();

Impact on CLI ​

The modulus add-module command is simplified by this generator:

  • Before: The CLI had to modify ModuleRegistration.cs to add the new module's registration calls
  • After: The CLI only needs to create the module projects and add them to the solution. The generator picks up the new IModuleRegistration implementation automatically on the next build

Generator Diagnostic ​

IDSeverityMessage
MODGEN004WarningIModuleRegistration implementation is missing ConfigureServices() or ConfigureEndpoints()

If a type implements IModuleRegistration but is missing one of the required static methods, the generator emits a warning and skips that module from auto-registration.

See Also ​

Released under the MIT License.