How should I register my mongodb service that uses the MongoClient, Singleton or scoped? How should I register my mongodb service that uses the MongoClient, Singleton or scoped? mongodb mongodb

How should I register my mongodb service that uses the MongoClient, Singleton or scoped?


The MongoDB .NET Driver reference documentation for version 2.10 explains on the Reference > Driver > Connecting page in the Mongo Client Re-use section that:

It is recommended to store a MongoClient instance in a global place, either as a static variable or in an IoC container with a singleton lifetime.

With regards to Mongo Database Re-use it doesn't mention a singleton lifetime but it does say it "is thread-safe and is safe to be stored globally", so I would interpret that to mean it can be stored safely as a singleton if that's what your implementation desired, but it doesn't need to be if you prefer another lifetime.

The implementation of IMongoDatabase provided by a MongoClient is thread-safe and is safe to be stored globally or in an IoC container.

It's the same with regards to Mongo Collection Re-use:

The implementation of IMongoCollection<TDocument> ultimately provided by a MongoClient is thread-safe and is safe to be stored globally or in an IoC container.

So again I'd interpret that to mean the choice of lifetime is up to your specific requirements.

It seems it's only the MongoClient that carries a recommendation to use a singleton lifetime.


Well its complicated.

First of all MongoClient can be singleton, so all services that uses MongoClient can be singletons as well. Its important cause singleton service cannot depends on service with shorter life (Scoped, Transient).

Now about UserService. All its dependancies is singletons and service itself don't stores any data (no fields, no props) that should live limited time or any data about particular user etc.

So it can be singleton!

But if you decided to add scoped dependancy or store any data in it:

public class UserService{    private readonly IMongoCollection<User> users;    private readonly long userCount; //this one    public UserService(IBookstoreDatabaseSettings settings)    {        var client = new MongoClient(settings.ConnectionString);        var database = client.GetDatabase(settings.DatabaseName);        users = database.GetCollection<User>(settings.UsersCollectionName);        userCount = users.Find(_ => true).CountDocuments();    }}

then you have to make it at least Scoped.


Btw it's much easier to have MongoClient as singleton in DI:

services.AddSingleton<IMongoClient>(s =>     new MongoClient(Configuration.GetConnectionString("MongoDb")));

and then use it in all services:

public class UserService{    private readonly IMongoCollection<User> users;    public UserService(IMongoClient mongoClient)    {        var database = mongoClient.GetDatabase("DatabaseName");        users = database.GetCollection<User>(settings.UsersCollectionName);    }}

Or if you will use just one database in your app you can move IMongoDatabase to DI as well and then you don’t need to get it every time in the service constructor.


Thank you for sharing, I am working on a MongoDB and .net core project. I have one DB with multiple collections. In start-up classservices.AddSingleton(s => { return new MongoClient(con.ConnectionString).GetDatabase(con.DatabaseName); });

My connection string and DB info are stored inside my appSetting.json.Now in my repo, I inject

mongoDBClient.GetCollection<SomeClass>(GetCollectionNameFromAppSetting((settings.CollectionName)));

Since I am having one Database would that be ok to have that registered as a singleton? or should I change it