# How to Add a New Database Provider to OpenDeepWiki: A Complete Implementation Guide

> Learn how to add a new database provider to OpenDeepWiki with this complete guide. Implement DbContext factories and extensions for dynamic loading. Explore AIDotNet/OpenDeepWiki features.

- Repository: [AIDotNet/OpenDeepWiki](https://github.com/aidotnet/opendeepwiki)
- Tags: how-to-guide
- Published: 2026-02-16

---

**To add a new database provider to OpenDeepWiki, create a new project implementing the DbContext, IContextFactory, and ServiceCollectionExtensions following the naming convention `AddOpenDeepWiki{Provider}`, then register it in [`DatabaseServiceExtensions.cs`](https://github.com/AIDotNet/OpenDeepWiki/blob/main/DatabaseServiceExtensions.cs) to enable dynamic loading via configuration.**

OpenDeepWiki uses a modular architecture based on **dependency injection and dynamic assembly loading** to support multiple database backends. This guide walks you through the exact steps to add a new database provider to OpenDeepWiki, following the established patterns used for SQLite and PostgreSQL implementations.

## Understanding the Database Provider Architecture

### Core Components

The architecture centers on three abstractions defined in the main project:

- **`MasterDbContext`**: The base DbContext that all providers must inherit from
- **`IContext`**: Interface abstracting database operations
- **`IContextFactory`**: Factory interface for creating database contexts

Each provider lives in its own project under `src/EFCore/` (e.g., `OpenDeepWiki.Sqlite`, `OpenDeepWiki.Postgresql`).

### Dynamic Loading Mechanism

The entry point [`src/OpenDeepWiki/Infrastructure/DatabaseServiceExtensions.cs`](https://github.com/AIDotNet/OpenDeepWiki/blob/main/src/OpenDeepWiki/Infrastructure/DatabaseServiceExtensions.cs) orchestrates provider selection through configuration:

1. Reads `Database:Type` from [`appsettings.json`](https://github.com/AIDotNet/OpenDeepWiki/blob/main/appsettings.json) or the `DB_TYPE` environment variable
2. Dynamically loads the corresponding assembly using `Assembly.Load`
3. Reflectively invokes the extension method `AddOpenDeepWiki{Provider}` to register services

This design allows adding new database support without modifying the core application code—only configuration changes are needed at runtime.

## Step-by-Step Implementation Guide

### Step 1: Create the Provider Project

Create a new class library project in `src/EFCore/OpenDeepWiki.MySql` (replace "MySql" with your target database).

Add the required NuGet packages for your EF Core provider (e.g., `Pomelo.EntityFrameworkCore.MySql` for MySQL) and add a project reference to the main OpenDeepWiki project.

### Step 2: Implement the DbContext

Create a DbContext that inherits from `MasterDbContext`:

```csharp
using Microsoft.EntityFrameworkCore;
using OpenDeepWiki.EFCore;

namespace OpenDeepWiki.MySql;

public class MySqlDbContext : MasterDbContext
{
    public MySqlDbContext(DbContextOptions<MySqlDbContext> options) 
        : base(options) 
    { 
    }
}

```

### Step 3: Implement the ContextFactory

Implement `IContextFactory` to handle context creation:

```csharp
using Microsoft.EntityFrameworkCore;
using OpenDeepWiki.EFCore;

namespace OpenDeepWiki.MySql;

public class MySqlContextFactory : IContextFactory
{
    private readonly IDbContextFactory<MySqlDbContext> _factory;

    public MySqlContextFactory(IDbContextFactory<MySqlDbContext> factory)
    {
        _factory = factory ?? throw new ArgumentNullException(nameof(factory));
    }

    public IContext CreateContext() => _factory.CreateDbContext();
}

```

### Step 4: Create the ServiceCollection Extension

This is the critical integration point. The class name must follow the pattern `{Provider}ServiceCollectionExtensions` and the method must be named `AddOpenDeepWiki{Provider}`:

```csharp
using Microsoft.EntityFrameworkCore;
using OpenDeepWiki.EFCore;

namespace OpenDeepWiki.MySql;

public static class MySqlServiceCollectionExtensions
{
    public static IServiceCollection AddOpenDeepWikiMySql(
        this IServiceCollection services,
        string connectionString)
    {
        // Register pooled DbContext factory
        services.AddPooledDbContextFactory<MySqlDbContext>(
            options => options.UseMySql(
                connectionString,
                ServerVersion.AutoDetect(connectionString)));

        // Register IContext for direct injection
        services.AddScoped<IContext>(sp => 
            sp.GetRequiredService<IDbContextFactory<MySqlDbContext>>()
              .CreateDbContext());

        // Register IContextFactory for factory pattern usage
        services.AddSingleton<IContextFactory, MySqlContextFactory>();

        return services;
    }
}

```

### Step 5: Register the Provider in DatabaseServiceExtensions

Modify [`src/OpenDeepWiki/Infrastructure/DatabaseServiceExtensions.cs`](https://github.com/AIDotNet/OpenDeepWiki/blob/main/src/OpenDeepWiki/Infrastructure/DatabaseServiceExtensions.cs) to handle your new provider type. Add a case to the switch expression and implement the loading logic:

```csharp
private static IServiceCollection AddMySql(IServiceCollection services, string connectionString)
{
    var assembly = LoadProviderAssembly("OpenDeepWiki.MySql");
    
    var extensionType = assembly.GetType("OpenDeepWiki.MySql.MySqlServiceCollectionExtensions")
        ?? throw new InvalidOperationException("找不到 MySqlServiceCollectionExtensions 类型");

    var method = extensionType.GetMethod("AddOpenDeepWikiMySql")
        ?? throw new InvalidOperationException("找不到 AddOpenDeepWikiMySql 方法");

    method.Invoke(null, [services, connectionString]);
    return services;
}

```

Then update the switch expression in the main registration method:

```csharp
return dbType switch
{
    "sqlite" => AddSqlite(services, connectionString),
    "postgresql" or "postgres" => AddPostgresql(services, connectionString),
    "mysql" => AddMySql(services, connectionString),  // 新增
    _ => throw new InvalidOperationException($"不支持的数据库类型: {dbType}")
};

```

### Step 6: Configure and Test

Update your [`appsettings.json`](https://github.com/AIDotNet/OpenDeepWiki/blob/main/appsettings.json) to use the new provider:

```json
{
  "Database": {
    "Type": "mysql"
  },
  "ConnectionStrings": {
    "Default": "Server=localhost;Database=opendeepwiki;User=root;Password=yourpassword;"
  }
}

```

Run the application to verify the dynamic loading works correctly:

```bash
dotnet run --project src/OpenDeepWiki/OpenDeepWiki.csproj

```

## Key Implementation Details

### Naming Conventions

The dynamic loading mechanism relies on strict naming conventions:

- **Assembly name**: `OpenDeepWiki.{Provider}` (e.g., `OpenDeepWiki.MySql`)
- **Extension class**: `{Provider}ServiceCollectionExtensions` (e.g., `MySqlServiceCollectionExtensions`)
- **Extension method**: `AddOpenDeepWiki{Provider}` (e.g., `AddOpenDeepWikiMySql`)
- **Configuration value**: Lowercase provider name (e.g., `"mysql"`, `"sqlite"`, `"postgresql"`)

### Required Service Registrations

Every provider extension must register three core services:

1. **`AddPooledDbContextFactory<TContext>`**: Enables efficient DbContext pooling
2. **`IContext`**: Scoped service for direct database access
3. **`IContextFactory`**: Singleton factory for creating contexts on demand

Failure to register any of these will result in runtime dependency resolution errors when the application attempts to instantiate repository classes.

## Summary

- **OpenDeepWiki** uses dynamic assembly loading to support multiple database providers without recompiling the core application.
- To add a new database provider to OpenDeepWiki, create a new project under `src/EFCore/` implementing `MasterDbContext`, `IContextFactory`, and the `AddOpenDeepWiki{Provider}` extension method.
- Register the provider in [`DatabaseServiceExtensions.cs`](https://github.com/AIDotNet/OpenDeepWiki/blob/main/DatabaseServiceExtensions.cs) by adding a case to the switch expression and implementing the assembly loading logic.
- Follow the strict naming conventions: assembly `OpenDeepWiki.{Provider}`, class `{Provider}ServiceCollectionExtensions`, method `AddOpenDeepWiki{Provider}`.
- Configure the new provider via `Database:Type` in [`appsettings.json`](https://github.com/AIDotNet/OpenDeepWiki/blob/main/appsettings.json) or the `DB_TYPE` environment variable.

## Frequently Asked Questions

### What is the minimum implementation required to add a new database provider to OpenDeepWiki?

At minimum, you must create a DbContext inheriting from `MasterDbContext`, implement `IContextFactory` for context creation, and provide a static extension method named `AddOpenDeepWiki{Provider}` in a class named `{Provider}ServiceCollectionExtensions`. This method must register `AddPooledDbContextFactory`, `IContext`, and `IContextFactory` with the dependency injection container.

### Can I add a database provider without modifying the core OpenDeepWiki project?

No, you must modify [`src/OpenDeepWiki/Infrastructure/DatabaseServiceExtensions.cs`](https://github.com/AIDotNet/OpenDeepWiki/blob/main/src/OpenDeepWiki/Infrastructure/DatabaseServiceExtensions.cs) to add a new case to the switch expression that handles your provider type. However, once registered, the provider assembly can be maintained independently, and the core application will dynamically load it at runtime based on configuration without requiring further code changes.

### What naming convention must the extension method follow for dynamic loading to work?

The extension method must be named exactly `AddOpenDeepWiki{Provider}` where `{Provider}` matches the provider name used in the assembly `OpenDeepWiki.{Provider}` and the class `{Provider}ServiceCollectionExtensions`. For example, for MySQL, the method must be `AddOpenDeepWikiMySql`, the class `MySqlServiceCollectionExtensions`, and the assembly `OpenDeepWiki.MySql`. The configuration value should be lowercase: `"mysql"`.

### How does OpenDeepWiki handle database migrations for multiple providers?

Each database provider project maintains its own migrations folder within its project directory (e.g., `src/EFCore/OpenDeepWiki.MySql/Migrations`). When adding a new provider, you generate migrations using the EF Core CLI targeting your new project: `dotnet ef migrations add Initial -p src/EFCore/OpenDeepWiki.MySql -s src/OpenDeepWiki`. This keeps provider-specific SQL dialects isolated while allowing the core domain models to remain consistent across all providers.