Skip to content

Use singleton MongoClient in DI and create required indexes on startup #2

@NandanDevHub

Description

@NandanDevHub

@MohanedZekry, I was just going through the project uses MongoDB with a clean architecture, but I did not see an explicit singleton registration for IMongoClient, and I did not find an index creation step for collections like Users. Please correct me if I missed it.

The thing is basically:

  1. MongoClient is thread safe and should be single instance per app to reuse connection pools and reduce overhead
  2. Creating indexes at startup avoids silent duplicates and gives a clear error from the database which is easy to handle

I would suggest a changes:

  1. DI lifetimes
builder.Services.AddSingleton<IMongoClient>(_ =>
    new MongoClient(builder.Configuration.GetConnectionString("MongoDb")));

builder.Services.AddScoped(sp =>
    sp.GetRequiredService<IMongoClient>().GetDatabase(
        builder.Configuration["MongoDB:DatabaseName"] ?? "appdb"));
  1. Create indexes during app start in an idempotent way
using var scope = app.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<IMongoDatabase>();
var users = db.GetCollection<User>("Users");

var emailIndex = new CreateIndexModel<User>(
    Builders<User>.IndexKeys.Ascending(u => u.Email),
    new CreateIndexOptions { Unique = true });

await users.Indexes.CreateOneAsync(emailIndex);

You can also test it via

  1. Try two parallel creates with the same email
  2. Before change you may get duplicate records or late failures in app logic
  3. After change Mongo will return a duplicate key error directly which can be handled in a simple way

Let me know if I can raise a PR that adds the DI update and simple index creation code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions