Skip to content
bitzorcas
中EN

Concept

Module Lifecycle & Modularity Engine

In-depth breakdown of the BitzOrcas.Modularity engine: topological dependency graph resolution, ConfigureServices, and UseModule lifecycle hooks.

Last updated

Module Lifecycle & Modularity Engine

During the scaling of an enterprise Modular Monolith, a frequent architectural smell is the uncontrolled growth of Program.cs. When hundreds of services and endpoints are wired inline within the host entrypoint, initialization order becomes fragile, and implicit dependencies cause runtime failures.

BitzOrcas.Modern resolves this via BitzOrcas.Modularity and the BitzOrcas.Modularity.Generator source generator, encapsulating each business domain into an autonomous module definition with explicit dependencies and automated lifecycle management.


1. Module Definition Contract: IModuleDefinition and [DependsOn]

Each module defines a module entry class implementing IModuleDefinition in its Contracts or Application root, declaring explicit dependencies using [DependsOn]:

using System;
using BitzOrcas.Modularity;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace BitzOrcas.Modules.Litigation;
/// <summary>
/// Litigation module definition declaring strong prerequisites on Identity and Notifications.
/// </summary>
[DependsOn(typeof(BitzOrcas.Platform.Identity.Contracts.IdentityModule))]
[DependsOn(typeof(BitzOrcas.Platform.Notifications.Contracts.NotificationsModule))]
public sealed class LitigationModule : IModuleDefinition
{
public string ModuleName => "Litigation";
public int Order => 100;
/// <summary>
/// Service registration phase: configure repositories, domain services, and external clients.
/// </summary>
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// 1. Bind module-specific configuration
services.AddOptions<LitigationOptions>()
.Bind(configuration.GetSection("Modules:Litigation"))
.ValidateDataAnnotations();
// 2. Register module-specific services
services.AddScoped<ILegalCaseNumberGenerator, LegalCaseNumberGenerator>();
}
/// <summary>
/// Middleware pipeline phase: execute after the host application pipeline is configured.
/// </summary>
public void UseModule(IApplicationBuilder app)
{
// Mount custom middleware, health checks, or webhook routing
}
}

2. Topological Sort & Dependency Resolution

At host startup, BitzOrcas.Modularity models all declared modules as a Directed Acyclic Graph (DAG) and executes a topological sort:

IdentityModule
(Core Tenancy & Auth)

NotificationsModule
(Alerts & Mail)

WorkflowModule
(BPM Engine)

LitigationModule
(Core Legal Domain)

LegalConnectorsModule
(Cloud Sync)

Invariant Rules & Guarantees

  1. Foundational Modules First: IdentityModule is guaranteed to finish its ConfigureServices execution before downstream consumers execute;
  2. Circular Dependency Detection: If Module A depends on B while B depends on A, the engine throws an immediate InvalidModuleDependencyException at build/startup, preventing corrupted states;
  3. Scoped Configuration Access: Modules access their configuration strictly under configuration.GetSection("Modules:<ModuleName>"), preserving clean setting boundaries.

3. Clean Host Entrypoint (Program.cs)

With the modularity engine, src/Hosts/BitzOrcas.Api remains concise and maintainable:

using BitzOrcas.Modularity;
var builder = WebApplication.CreateBuilder(args);
// 1. Discover, sort, and register all modules
builder.Services.AddModularMonolith(builder.Configuration);
var app = builder.Build();
// 2. Mount module middlewares in topological order
app.UseModularMonolith();
app.Run();

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%