Madoka.Framework.EntityFrameworkCore
1.0.1.3
dotnet add package Madoka.Framework.EntityFrameworkCore --version 1.0.1.3
NuGet\Install-Package Madoka.Framework.EntityFrameworkCore -Version 1.0.1.3
<PackageReference Include="Madoka.Framework.EntityFrameworkCore" Version="1.0.1.3" />
<PackageVersion Include="Madoka.Framework.EntityFrameworkCore" Version="1.0.1.3" />
<PackageReference Include="Madoka.Framework.EntityFrameworkCore" />
paket add Madoka.Framework.EntityFrameworkCore --version 1.0.1.3
#r "nuget: Madoka.Framework.EntityFrameworkCore, 1.0.1.3"
#:package Madoka.Framework.EntityFrameworkCore@1.0.1.3
#addin nuget:?package=Madoka.Framework.EntityFrameworkCore&version=1.0.1.3
#tool nuget:?package=Madoka.Framework.EntityFrameworkCore&version=1.0.1.3
Madoka.Framework
English | 简体中文
A multi-tenant, layered framework built on ABP Framework (.NET 10 / ABP 10.5). It integrates commonly used ABP modules out of the box and ships with a custom Tailwind-based Razor Pages admin UI.
Features
- Integrates Identity, Tenant Management, Feature Management, Setting Management, Audit Logging, Background Jobs, Blob Storing, OpenIddict and more
- A unified
DbContextbase class - consumers simply inherit it to get all entities and configuration - Built-in admin UI (Users / Roles / Tenants / Feature Management / Audit Logs / Settings / Background Jobs pages) with collapsible sidebar and language switching
- The admin UI consumes data over HTTP APIs, and the API surface (audit logs, background jobs, settings, feature management, identity, tenant management, account) is fully exposed - front-end/back-end separated clients can use the exact same endpoints, and the Razor Pages UI can be dropped in a later version without losing any API capability
- Database migration tool pattern (
DbMigrator) that creates the database, applies migrations and seeds data automatically - Conventional API controllers and Swagger
Requirements
- .NET 10 SDK
- A supported database (e.g. SQL Server, SQLite, PostgreSQL or MySQL) - the framework is database-provider agnostic
- (Optional) Node.js - only needed to rebuild Tailwind styles
Installation
Reference the packages you need from NuGet (prefer the latest preview version):
| Package | Purpose |
|---|---|
Madoka.Framework.Domain.Shared |
Constants, localization resources, error codes (base dependency for all projects) |
Madoka.Framework.Domain |
Domain layer: entities, domain services, module integrations, OpenIddict seeding |
Madoka.Framework.Application.Contracts |
Application service interfaces, DTOs, permission definitions |
Madoka.Framework.Application |
Application service implementations |
Madoka.Framework.EntityFrameworkCore |
EF Core integration: inheritable DbContext base class and module entity mappings |
Madoka.Framework.HttpApi |
HTTP API (conventional API controllers) |
Madoka.Framework.HttpApi.Client |
HTTP API client proxies (used by the admin UI and external callers to call the API over HTTP) |
Madoka.Framework.Web |
MVC / Razor Pages admin UI (Razor class library) |
Domain.Shared / Domain are the required foundation; add EntityFrameworkCore for persistence, HttpApi for APIs, and Web for the admin UI.
Quick Start
The steps below create a layered solution named MyApp. A complete runnable example is available in the sample/ directory of this repository.
1. Define your own DbContext
The framework requires consumers to register their own DbContext. Create an EF Core project (e.g. MyApp.EntityFrameworkCore), reference Madoka.Framework.EntityFrameworkCore, and inherit the generic base class:
using Madoka.Framework.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace MyApp;
public class MyAppDbContext : MadokaFrameworkDbContext<MyAppDbContext>
{
public MyAppDbContext(DbContextOptions<MyAppDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder); // Required: includes all ABP module entity configuration
// Add your own entity configuration here
//builder.Entity<YourEntity>(b =>
//{
// b.ToTable("YourEntities");
//});
}
}
2. Configure the EF Core module
Register the DbContext in your EF Core module and point the migrations assembly to your own project (migrations are maintained by the consumer):
using Madoka.Framework.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.Modularity;
[DependsOn(typeof(MyAppDomainModule), typeof(MadokaFrameworkEntityFrameworkCoreModule))]
public class MyAppEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<MyAppDbContext>(options =>
{
options.AddDefaultRepositories();
});
Configure<AbpDbContextOptions>(options =>
{
options.UseSqlServer(b => b.MigrationsAssembly("MyApp.EntityFrameworkCore"));
});
}
}
The example above uses SQL Server. The framework itself is database-provider agnostic: reference the provider package you need (e.g.
Volo.Abp.EntityFrameworkCore.SqlServer,Volo.Abp.EntityFrameworkCore.Sqlite,Volo.Abp.EntityFrameworkCore.NpgsqlorVolo.Abp.EntityFrameworkCore.MySql) and call the matchingUse...extension in your module.
3. Create the initial migration
Add a design-time factory in MyApp.EntityFrameworkCore (recommended):
using Madoka.Framework.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
public class MyAppDbContextFactory : IDesignTimeDbContextFactory<MyAppDbContext>
{
public MyAppDbContext CreateDbContext(string[] args)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../MyApp.Web/"))
.AddJsonFile("appsettings.json", optional: false)
.Build();
return new MyAppDbContext(
new DbContextOptionsBuilder<MyAppDbContext>()
.UseSqlServer(configuration.GetConnectionString("Default"),
b => b.MigrationsAssembly("MyApp.EntityFrameworkCore"))
.Options);
}
}
Then generate the migration:
dotnet ef migrations add Initial --context MyAppDbContext \
--project MyApp.EntityFrameworkCore --startup-project MyApp.EntityFrameworkCore
4. Create the DbMigrator
Create a console project (e.g. MyApp.DbMigrator) referencing MyApp.EntityFrameworkCore and Madoka.Framework.Application.Contracts, and call the framework's migration service from a hosted service:
public class DbMigratorHostedService : IHostedService
{
private readonly MadokaFrameworkDbMigrationService _migrationService;
public DbMigratorHostedService(MadokaFrameworkDbMigrationService migrationService)
=> _migrationService = migrationService;
public async Task StartAsync(CancellationToken cancellationToken)
=> await _migrationService.MigrateAsync(); // Creates the database, migrates and seeds (admin user, OpenIddict clients, etc.)
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
Module declaration:
[DependsOn(
typeof(AbpAutofacModule),
typeof(MyAppEntityFrameworkCoreModule),
typeof(MadokaFrameworkApplicationContractsModule)
)]
public class MyAppDbMigratorModule : AbpModule { }
Configure the connection string and OpenIddict clients (created during seeding) in appsettings.json:
{
"ConnectionStrings": {
"Default": "Server=localhost,1433;Database=MyApp;User Id=sa;Password=YourPassword;TrustServerCertificate=true"
},
"OpenIddict": {
"Applications": {
"MyApp_App": { "ClientId": "MyApp_App", "RootUrl": "https://localhost:44300" },
"MyApp_Swagger": { "ClientId": "MyApp_Swagger", "RootUrl": "https://localhost:44300/" }
}
}
}
Run it to create the database:
dotnet run --project MyApp.DbMigrator
5. Create the web host
Create a web project (e.g. MyApp.Web) referencing MyApp.EntityFrameworkCore and Madoka.Framework.Web. Host module:
[DependsOn(
typeof(MadokaFrameworkWebModule),
typeof(MyAppApplicationModule),
typeof(MyAppEntityFrameworkCoreModule),
typeof(AbpAutofacModule)
)]
public class MyAppWebModule : AbpModule { }
The framework's Razor Pages call the API over HTTP (through
IHttpClientProxy<T>), so your host module gets the HTTP client proxies automatically viaMadokaFrameworkWebModule. You only need to point the proxies at your own URL with theRemoteServicessetting below.
Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Host
.AddAppSettingsSecretsJson()
.UseAutofac()
.UseSerilog((context, services, config) =>
config.ReadFrom.Configuration(context.Configuration).ReadFrom.Services(services));
await builder.AddApplicationAsync<MyAppWebModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
Key appsettings.json settings:
{
"App": {
"SelfUrl": "https://localhost:44300",
"HealthCheckUrl": "/health-status"
},
"RemoteServices": {
"Default": {
"BaseUrl": "https://localhost:44300"
}
},
"ConnectionStrings": {
"Default": "Server=localhost,1433;Database=MyApp;User Id=sa;Password=YourPassword;TrustServerCertificate=true"
},
"AuthServer": {
"Authority": "https://localhost:44300",
"RequireHttpsMetadata": true,
"CertificatePassPhrase": "Your certificate passphrase"
},
"StringEncryption": {
"DefaultPassPhrase": "Your encryption passphrase (16+ chars)"
}
}
Start the app and browse to https://localhost:44300, then sign in with the seeded administrator account (default admin@abp.io / 1q2w3E*).
Configuration Reference
| Key | Description |
|---|---|
ConnectionStrings:Default |
Database connection string |
App:SelfUrl |
Application's own URL (used for login redirects and URL generation) |
App:HealthCheckUrl |
Health check endpoint path |
RemoteServices:Default:BaseUrl |
API endpoint base URL used by the admin UI and HTTP client proxies (usually the same as SelfUrl) |
AuthServer:Authority |
Authentication server URL (usually the same as SelfUrl) |
AuthServer:CertificatePassPhrase |
Passphrase for the OpenIddict development certificate |
StringEncryption:DefaultPassPhrase |
Passphrase for encrypting sensitive data (must be changed in production) |
OpenIddict:Applications |
OpenIddict clients created by the DbMigrator during seeding |
Production Deployment
Generating the OpenIddict Signing Certificate
In production, OpenIddict expects signing and encryption credentials. Generate an openiddict.pfx file in your web project and set its password in AuthServer:CertificatePassPhrase:
dotnet dev-certs https -v -ep openiddict.pfx -p YourCertificatePassword
It is recommended to use two RSA certificates, distinct from the certificate(s) used for HTTPS: one for encryption, one for signing. For more information, see the OpenIddict certificate configuration and Configuring OpenIddict documentation.
Deploying
Deploying an application built on this framework follows the same process as deploying any .NET / ASP.NET Core application. Refer to ABP's deployment documentation for detailed guidance.
Custom Localization
The framework ships with localized texts for 20 languages. To add your own texts, follow these steps:
- Define a resource class in your
Domain.Sharedproject:[LocalizationResourceName("MyApp")] public class MyAppResource { } - Add language files
Localization/MyApp/en.json,zh-Hans.json, etc. (format:{ "Culture": "en", "Texts": { "Key": "Value" } }). - Register it in your module:
Configure<AbpVirtualFileSystemOptions>(o => o.FileSets.AddEmbedded<MyAppDomainSharedModule>()); Configure<AbpLocalizationOptions>(o => o.Resources.Add<MyAppResource>("zh-Hans").AddVirtualJson("/Localization/MyApp")); - Make sure
MyApp.Domain.Shared.csprojincludes:<EmbeddedResource Include="Localization\MyApp\*.json" /><GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>- A reference to the
Microsoft.Extensions.FileProviders.Embeddedpackage
Use it in pages with @inject IHtmlLocalizer<MyAppResource> L and @L["Key"]. The language switcher is provided by the framework UI.
Using the Integrated Modules
- Background Jobs: implement
AsyncBackgroundJob<TArgs>in the domain layer and enqueue withIBackgroundJobManager.EnqueueAsync(...); the Background Jobs page provides list / detail / retry / delete. - Blob Storing: use
IBlobContainer<TContainer>for database-backed blob storage (the default container is enabled). - Audit Logging: implement audit interfaces such as
IHasCreationTimeor annotate entities with[Audited]; the Audit Logs page lets you browse records. - Setting Management: define a
SettingDefinitionProviderto add settings, edit them from the Settings page, and read them withISettingProvider.GetOrNullAsync(...).
HTTP API & Front-end/Back-end Separation
Every management feature is exposed as a conventional HTTP API and can be consumed without the Razor Pages UI:
- Audit logs: list / detail with filters (execution time, user, URL, exceptions) via
IMadokaAuditLogAppService - Background jobs: list / detail / delete / retry via
IMadokaBackgroundJobAppService - Settings: get / update per provider (global
Gor tenantT) viaIMadokaFrameworkSettingsAppService - Feature management: get / update per provider via ABP's
IFeatureAppService - Identity / Tenant / Account: standard ABP services (
IIdentityUserAppService,IIdentityRoleAppService,ITenantAppService,IProfileAppService, permission APIs, etc.) - Tenant lookup for login pages: anonymous endpoint
ITenantLookupAppServicereturns the tenant list without authentication
The Razor Pages admin UI is an optional UI layer on top of these APIs - it injects the same service interfaces through IHttpClientProxy<T> and calls the API over HTTP with the current login cookie forwarded. Front-end/back-end separated clients authenticate with OpenIddict tokens and call the same endpoints. This keeps the API surface stable if the Razor Pages UI is removed in a future version.
All public types and members ship with Chinese XML documentation comments in the NuGet packages, so IntelliSense and the Object Browser show friendly descriptions without opening the source.
Sample Project
The sample/ directory of this repository contains a complete runnable example (Sample.Web + Sample.DbMigrator) demonstrating the standard integration, including a custom DbContext, migrations and localization.
FAQ
Q: Why do I have to register my own DbContext?
The framework no longer registers a default DbContext so that every consumer fully controls its own entities, migrations and database. Inheriting MadokaFrameworkDbContext<TDbContext> gives you all module entities without duplicating work.
Q: How do I customize the UI styles?
The framework UI uses Tailwind CSS (built on demand). To modify framework pages, rebuild wwwroot/css/tailwind.css under src/Madoka.Framework.Web (input tailwind.src.css, output tailwind.css, --minify). Consumers normally don't need to rebuild unless they fork the framework pages.
Q: Migrations report "no migrations found"?
Make sure your EF Core module configures UseSqlServer(b => b.MigrationsAssembly("Your.EntityFrameworkCore.Assembly")) and that migrations are generated in the consumer project.
Q: Permission errors after login?
Run the DbMigrator first to complete seeding; if you changed permission definitions, check that dynamic permission storage is enabled in PermissionManagement.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Madoka.Framework.Domain (>= 1.0.1.3)
- Microsoft.EntityFrameworkCore.Design (>= 10.0.11)
- Microsoft.EntityFrameworkCore.Tools (>= 10.0.11)
- Microsoft.Extensions.FileProviders.Embedded (>= 10.0.11)
- Volo.Abp.AuditLogging.Domain (>= 10.6.0)
- Volo.Abp.AuditLogging.Domain.Shared (>= 10.6.0)
- Volo.Abp.AuditLogging.EntityFrameworkCore (>= 10.6.0)
- Volo.Abp.Authorization (>= 10.6.0)
- Volo.Abp.BackgroundJobs.Abstractions (>= 10.6.0)
- Volo.Abp.BackgroundJobs.Domain (>= 10.6.0)
- Volo.Abp.BackgroundJobs.Domain.Shared (>= 10.6.0)
- Volo.Abp.BackgroundJobs.EntityFrameworkCore (>= 10.6.0)
- Volo.Abp.BlobStoring.Database.Domain (>= 10.6.0)
- Volo.Abp.BlobStoring.Database.Domain.Shared (>= 10.6.0)
- Volo.Abp.BlobStoring.Database.EntityFrameworkCore (>= 10.6.0)
- Volo.Abp.Caching (>= 10.6.0)
- Volo.Abp.Emailing (>= 10.6.0)
- Volo.Abp.EntityFrameworkCore (>= 10.6.0)
- Volo.Abp.FeatureManagement.Domain (>= 10.6.0)
- Volo.Abp.FeatureManagement.Domain.Shared (>= 10.6.0)
- Volo.Abp.FeatureManagement.EntityFrameworkCore (>= 10.6.0)
- Volo.Abp.GlobalFeatures (>= 10.6.0)
- Volo.Abp.Identity.Domain (>= 10.6.0)
- Volo.Abp.Identity.Domain.Shared (>= 10.6.0)
- Volo.Abp.Identity.EntityFrameworkCore (>= 10.6.0)
- Volo.Abp.OpenIddict.Domain (>= 10.6.0)
- Volo.Abp.OpenIddict.Domain.Shared (>= 10.6.0)
- Volo.Abp.OpenIddict.EntityFrameworkCore (>= 10.6.0)
- Volo.Abp.PermissionManagement.Domain (>= 10.6.0)
- Volo.Abp.PermissionManagement.Domain.Identity (>= 10.6.0)
- Volo.Abp.PermissionManagement.Domain.OpenIddict (>= 10.6.0)
- Volo.Abp.PermissionManagement.Domain.Shared (>= 10.6.0)
- Volo.Abp.PermissionManagement.EntityFrameworkCore (>= 10.6.0)
- Volo.Abp.SettingManagement.Domain (>= 10.6.0)
- Volo.Abp.SettingManagement.Domain.Shared (>= 10.6.0)
- Volo.Abp.SettingManagement.EntityFrameworkCore (>= 10.6.0)
- Volo.Abp.TenantManagement.Domain (>= 10.6.0)
- Volo.Abp.TenantManagement.Domain.Shared (>= 10.6.0)
- Volo.Abp.TenantManagement.EntityFrameworkCore (>= 10.6.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Madoka.Framework.EntityFrameworkCore:
| Package | Downloads |
|---|---|
|
Madoka.Framework.Web
Madoka.Framework MVC / Razor Pages UI module with custom admin pages (audit logs, settings, feature management, background jobs, identity and tenant management) and Tailwind layout. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.1.3 | 52 | 8/23/2026 |
| 1.0.1.2 | 48 | 8/21/2026 |
| 1.0.1.1 | 88 | 8/20/2026 |
| 1.0.1 | 75 | 8/20/2026 |
| 1.0.0-preview.9 | 47 | 8/20/2026 |
| 1.0.0-preview.8 | 51 | 8/20/2026 |
| 1.0.0-preview.7 | 49 | 8/20/2026 |
| 1.0.0-preview.6 | 61 | 8/16/2026 |
| 1.0.0-preview.5 | 58 | 8/16/2026 |
| 1.0.0-preview.4 | 66 | 8/15/2026 |
| 1.0.0-preview.3 | 58 | 8/12/2026 |
| 1.0.0-preview.2 | 55 | 8/12/2026 |
| 1.0.0-preview.1 | 53 | 8/12/2026 |