You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6中如何注册带MongoDB依赖与构造函数参数的MongoRepository类

.NET 6 注册 MongoRepository 依赖注入指南

第一步:注册 MongoDB 核心依赖

MongoRepository<T> 依赖 IMongoDatabase,先在 Program.cs 中完成 MongoClient 和 IMongoDatabase 的注册:

var builder = WebApplication.CreateBuilder(args);

// 从配置文件读取MongoDB连接字符串和数据库名
var mongoConnString = builder.Configuration.GetConnectionString("MongoDB");
var dbName = builder.Configuration["MongoDB:DatabaseName"];

// 注册MongoClient单例
builder.Services.AddSingleton<IMongoClient>(_ => new MongoClient(mongoConnString));

// 注册IMongoDatabase单例,依赖已注册的MongoClient
builder.Services.AddSingleton<IMongoDatabase>(sp =>
{
    var client = sp.GetRequiredService<IMongoClient>();
    return client.GetDatabase(dbName);
});

第二步:注册泛型仓库

根据业务场景选择以下两种注册方式:

场景1:为特定实体单独注册

如果每个实体对应固定的集合名(比如 Item 对应 Items 集合),直接为每个实体类型手动注册:

// 注册Item实体的仓库
builder.Services.AddScoped<IRepository<Item>>(sp =>
{
    var db = sp.GetRequiredService<IMongoDatabase>();
    return new MongoRepository<Item>(db, "Items");
});

// 注册Category实体的仓库
builder.Services.AddScoped<IRepository<Category>>(sp =>
{
    var db = sp.GetRequiredService<IMongoDatabase>();
    return new MongoRepository<Category>(db, "Categories");
});

场景2:通用自动注册(按约定生成集合名)

如果想让集合名遵循统一约定(比如实体类名转复数),可以用开放泛型的工厂方式自动注册所有实现 IEntity 的实体:

// 注册所有IRepository<T>的实现为MongoRepository<T>,自动生成集合名
builder.Services.AddScoped(typeof(IRepository<>), (sp, serviceType) =>
{
    // 获取当前要解析的仓库对应的实体类型T
    var entityType = serviceType.GetGenericArguments()[0];
    
    // 自定义集合名规则:实体类名转复数(可按需修改)
    var collectionName = $"{entityType.Name}s";
    
    var db = sp.GetRequiredService<IMongoDatabase>();
    
    // 动态创建MongoRepository<T>实例
    return Activator.CreateInstance(
        typeof(MongoRepository<>).MakeGenericType(entityType),
        db,
        collectionName
    );
});

补充:结合配置文件映射集合名

如果需要更灵活的集合名配置,可在 appsettings.json 中定义实体与集合的映射:

{
  "MongoDB": {
    "ConnectionString": "mongodb://localhost:27017",
    "DatabaseName": "CatalogDb",
    "CollectionMappings": {
      "Item": "ProductItems",
      "Category": "ProductCategories"
    }
  }
}

然后修改通用注册逻辑,优先读取配置中的集合名:

builder.Services.AddScoped(typeof(IRepository<>), (sp, serviceType) =>
{
    var entityType = serviceType.GetGenericArguments()[0];
    var config = sp.GetRequiredService<IConfiguration>();
    
    // 优先从配置取集合名,无配置则用默认复数规则
    var collectionName = config[$"MongoDB:CollectionMappings:{entityType.Name}"] 
                         ?? $"{entityType.Name}s";
    
    var db = sp.GetRequiredService<IMongoDatabase>();
    
    return Activator.CreateInstance(
        typeof(MongoRepository<>).MakeGenericType(entityType),
        db,
        collectionName
    );
});

生命周期说明

MongoRepository<T> 建议使用 Scoped 生命周期,与Web请求周期一致,符合.NET依赖注入的最佳实践。


内容的提问来源于stack exchange,提问作者Shivam Kumar Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 22:35:51