From ABP Sensei
Guides ABP Framework modular development: AbpModule class, [DependsOn] dependencies, lifecycle methods, plugin modules, and modular monolith architecture.
How this skill is triggered — by the user, by Claude, or both
Slash command
/abp-sensei:abp-modularityThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
A guide to modular application development in ABP Framework v10.4. The module system, dependency management, plugin modules, and best practices.
A guide to modular application development in ABP Framework v10.4. The module system, dependency management, plugin modules, and best practices.
ABP supports building fully modular applications and systems. Each module can contain its own entities, services, database integration, APIs, and UI components.
[DependsOn(
typeof(AbpAspNetCoreMvcModule),
typeof(AbpEntityFrameworkCoreModule),
typeof(AbpAutofacModule)
)]
public class BlogModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context) { }
public override void ConfigureServices(ServiceConfigurationContext context)
{
// DI registration, module configuration
Configure<AbpDbConnectionOptions>(options =>
{
options.ConnectionStrings.Default = "...";
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseMvcWithDefaultRoute();
}
public override void OnApplicationShutdown(ApplicationShutdownContext context) { }
}
| Method | When It Runs | Usage |
|---|---|---|
PreConfigureServices | Before all ConfigureServices | Early configuration |
ConfigureServices | Service registration | DI registration, module settings |
PostConfigureServices | After all ConfigureServices | Late configuration |
OnPreApplicationInitialization | Before init | Pre-init logic |
OnApplicationInitialization | Application startup | Middleware pipeline |
OnPostApplicationInitialization | After init | Post-init logic |
OnApplicationShutdown | Application shutdown | Cleanup logic |
An Async version of each method is also available.
// Multiple within a single DependsOn
[DependsOn(typeof(AbpAspNetCoreMvcModule), typeof(AbpAutofacModule))]
public class BlogModule : AbpModule { }
// Multiple attributes
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
[DependsOn(typeof(AbpAutofacModule))]
public class BlogModule : AbpModule { }
At startup, ABP inspects the dependency graph and starts/shuts down modules in the correct order.
In rare cases, if your module consists of more than one assembly:
[DependsOn(...)]
[AdditionalAssembly(typeof(BlogService))] // A type from the target assembly
public class BlogModule : AbpModule { }
Warning: Use
AdditionalAssemblyonly when truly needed. NormallyDependsOnshould be preferred.
| Type | Description | Example |
|---|---|---|
| Framework Module | Infrastructure, integration, abstraction | Caching, EF Core, Validation, Logging |
| Application Module | Functional/business features | Blogging, Identity, Tenant Management |
Modules that can be loaded dynamically at runtime:
[DependsOn(typeof(AbpKernelModule))]
public class MyPluginModule : AbpModule { }
Plugin modules:
Package according to DDD layers:
Acme.Blog/
├── Acme.Blog.Domain.Shared # Constants, enums, localization
├── Acme.Blog.Domain # Entities, repositories (interface)
├── Acme.Blog.Application.Contracts # DTOs, service interfaces
├── Acme.Blog.Application # Application services
├── Acme.Blog.EntityFrameworkCore # DbContext, migrations
├── Acme.Blog.HttpApi # API controllers
└── Acme.Blog.HttpApi.Client # Dynamic C# clients
Design independently of the database provider — don't make the Domain/Application layers depend on EF Core
Each module can define its own connection string:
Configure<AbpDbConnectionOptions>(options =>
{
options.ConnectionStrings["Blog"] = "...";
});
Use the Options pattern for module configuration:
public class BlogOptions
{
public int MaxPostLength { get; set; } = 5000;
}
// Configure it in the Module
Configure<BlogOptions>(options => options.MaxPostLength = 10000);
Use IRepository for reusable modules — don't use DbContext directly
# DDD module
abp new-module Acme.Blog -t module:ddd
# Modern module
abp new-module Acme.Blog --modern
# Add to a specific solution
abp new-module Acme.Blog -t module:ddd -ts Acme.Crm.sln
# With EF + MVC support
abp new-module Acme.Blog -t module:ddd -d ef -u mvc
# Install a NuGet module
abp install-module Volo.Blogging
# Install a local module
abp install-local-module ../Acme.Blogging
# Add a package
abp add-package Volo.Abp.Blogging
Extending pre-built modules:
// Extending an entity
ObjectExtensionManager.Instance
.MapEfCoreProperty<IdentityUser, string>(
"Title",
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasMaxLength(64);
}
);
A modular monolith offers the advantages of microservices within a single process:
abp new Acme.Crm --template app-nolayers --modern --modular
npx claudepluginhub burakdmir/abp-skills --plugin abp-senseiProvides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.