Madoka.Framework.EntityFrameworkCore 1.0.1.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package Madoka.Framework.EntityFrameworkCore --version 1.0.1.2
                    
NuGet\Install-Package Madoka.Framework.EntityFrameworkCore -Version 1.0.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Madoka.Framework.EntityFrameworkCore" Version="1.0.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Madoka.Framework.EntityFrameworkCore" Version="1.0.1.2" />
                    
Directory.Packages.props
<PackageReference Include="Madoka.Framework.EntityFrameworkCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Madoka.Framework.EntityFrameworkCore --version 1.0.1.2
                    
#r "nuget: Madoka.Framework.EntityFrameworkCore, 1.0.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Madoka.Framework.EntityFrameworkCore@1.0.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Madoka.Framework.EntityFrameworkCore&version=1.0.1.2
                    
Install as a Cake Addin
#tool nuget:?package=Madoka.Framework.EntityFrameworkCore&version=1.0.1.2
                    
Install as a Cake Tool

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 DbContext base 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.Npgsql or Volo.Abp.EntityFrameworkCore.MySql) and call the matching Use... 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 via MadokaFrameworkWebModule. You only need to point the proxies at your own URL with the RemoteServices setting 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:

  1. Define a resource class in your Domain.Shared project:
    [LocalizationResourceName("MyApp")]
    public class MyAppResource { }
    
  2. Add language files Localization/MyApp/en.json, zh-Hans.json, etc. (format: { "Culture": "en", "Texts": { "Key": "Value" } }).
  3. Register it in your module:
    Configure<AbpVirtualFileSystemOptions>(o => o.FileSets.AddEmbedded<MyAppDomainSharedModule>());
    Configure<AbpLocalizationOptions>(o =>
        o.Resources.Add<MyAppResource>("zh-Hans").AddVirtualJson("/Localization/MyApp"));
    
  4. Make sure MyApp.Domain.Shared.csproj includes:
    • <EmbeddedResource Include="Localization\MyApp\*.json" />
    • <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
    • A reference to the Microsoft.Extensions.FileProviders.Embedded package

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 with IBackgroundJobManager.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 IHasCreationTime or annotate entities with [Audited]; the Audit Logs page lets you browse records.
  • Setting Management: define a SettingDefinitionProvider to add settings, edit them from the Settings page, and read them with ISettingProvider.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 G or tenant T) via IMadokaFrameworkSettingsAppService
  • 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 ITenantLookupAppService returns 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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