Solid by design,
modular by nature.
A modular .NET 10 framework — orchestrate auth, persistence, messaging, and 131+ more modules effortlessly. No boilerplate, no rewrites, no limits.
Why developers choose Granit
Topological dependency resolution, lifecycle hooks, and conditional modules. Pick what you need — the graph resolves automatically.
EF Core interceptors for audit trails, soft delete, and entity versioning. Zero manual WHERE clauses, ever.
JWT + Keycloak/Entra ID/Cognito authentication, policy-based authorization, Vault integration, and GDPR privacy helpers.
Serilog + OpenTelemetry deliver logs, traces, and metrics automatically — debug faster with zero setup.
Shared database, schema-per-tenant, or database-per-tenant. Transparent query filters, no code changes.
Wolverine message bus with transactional outbox, webhooks, and a 6-channel notification engine.
Pick your modules, see the code
Toggle the modules you need — the code updates in real time. Each module declares its dependencies. Granit resolves the graph automatically.
[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitObservabilityModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitObservability(
context.Configuration);
}
} var builder = WebApplication.CreateBuilder(args);
builder.AddGranit<AppModule>();
var app = builder.Build();
app.UseGranit();
app.Run(); [DependsOn(typeof(GranitPersistenceModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitNotificationsModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitNotificationsModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitObservabilityModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitObservability(
context.Configuration);
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitSecurityModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitObservabilityModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitObservability(
context.Configuration);
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
}
}[DependsOn(typeof(GranitPersistenceModule))]
[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitDbContext<AppDbContext>(
options => options.UseNpgsql(
context.Configuration
.GetConnectionString("Default")));
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
// Pick modules above to see the code
}
}[DependsOn(typeof(GranitSecurityModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
}
}[DependsOn(typeof(GranitObservabilityModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitObservability(
context.Configuration);
}
}[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitObservabilityModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitObservability(
context.Configuration);
}
}[DependsOn(typeof(GranitNotificationsModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
}
}[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
}
}[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
}
}[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
}
}[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitNotificationsModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
}[DependsOn(typeof(GranitSecurityModule))]
[DependsOn(typeof(GranitObservabilityModule))]
[DependsOn(typeof(GranitNotificationsModule))]
[DependsOn(typeof(GranitLocalizationModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(
ServiceConfigurationContext context)
{
context.Services.AddGranitAuthentication()
.AddKeycloak(context.Configuration);
context.Services.AddGranitObservability(
context.Configuration);
context.Services.AddGranitNotifications()
.AddSmtp(context.Configuration);
context.Services.AddGranitLocalization(
options => options.DefaultCulture = "en");
}
} Compliance built in, not bolted on
Every module is designed with GDPR and ISO 27001 in mind. Audit trails, encryption, right to erasure, tenant isolation — architectural constraints, not afterthoughts.
Ready to build on solid ground?
Start with the getting started guide, explore the module reference, or dive into the architecture decisions that shaped Granit.