Skip to main content

Working with MongoDB in .Net Core (Part 1) - Mongo Connection Manager


Connecting to Mongo Database C#

Mongo DB is a NoSQL document-oriented database which stores data in a JSON-like format. Mongo DB stores the data in a binary-encoded format called BSON. Every application connecting to Mongo DB will have a Mongo connection manager to create Mongo Clients and connect to database and collection to perform CRUD operations. Here is a sample of how a Mongo Connection manager would look like,


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Driver;

public class MongoConnectionManager : IMongoConnectionManager
{
    public IMongoClient client { get; set;}
    private readonly MongoDBConfigSettings _mongoDBSettings;
    //Setup Mongo Client in the connection Manager constructor when the instance is created, so that it can be dependency injected into other classes
    public MongoConnectionManager(IOptions<MongoDBConfigSettings> mongoDBSettings)
    {
        mongoDBSettings = _mongoDBSettings.Value;
        client = GetMongoClient();
    }
}

GetMongoClient - 

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
private IMongoClient GetMongoClient()
{
    try
    {
        var settings = new MongoClientSettings
        {
            ConnectionMode = ConnectionMode.Automatic,
            UseSSL = MongoDBSettings.UseSSL,
            //Get all the settings from Config (Can be in Spring Cloud or some project config files)
            MinConnectionPoolSize = MongoDBSettings.MinConnectionPoolSize,
            MaxConnectionIdleTime = new TimeSpan(0,0,0,0,MongoDBSettings.MaxConnectionIdleTime),
            ServerSelectionTimeout = new TimeSpan(0,0,0,0,MongoDBSettings.ServerSelectionTimeout),
            ConnectTimeout = new TimeSpan(0,0,0,0,MongoDBSettings.ConnectTimeout),
            SocketTimeout = new TimeSpan(0,0,0,0,MongoDBSettings.SocketTimeout)
        };
        var pack = new ConventionPack
        {
            new IgnoreExtraElementsConvention(true)
        };
        ConventionRegistry.Register("IgnoreConvention", pack, t => true);
        
        //Set up Read/Write Preferences
        var wc = new WriteConcern(WriteConcern.WMajority.W, new TimeSpan(0,0,0,0,MongoDBSettings.WriteTimeout));
        settings.WriteConcern = wc;
        settings.ReadPreference = ReadPreference.PrimaryPreferred;
        //Configuring the Mongo Server to connect
        var serverslist = MongoDBSettings.Servers;
        var servers = serverslist.Split(',');
        var mdbServerList = servers.Select(server=>server.Split(',').Select(addressportArray=>
                                       new MongoServerAddress(addressportArray[0], Convert.ToInt32(addressportArray[1])))).ToList();
        settings.Servers = mdbServerList;
        settings.Credential = MongoCredential.CreatePlainCredential("$external", MongoDBSettings.User, MongoDBSettings.Password);
        settings.RetryWrites = true;
        var connectionString = MongoDBSettings.MongoConnectionStringOverride;
        return !string.IsNullOrWhiteSpace(connectionString) ? new MongoClient(connectionString) : new MongoClient(settings);
    }
    catch (System.Exception ex)
    {
        throw ex;
    }
}

GetDatabase - 

1
2
3
4
5
private IMongoDatabase GetDatabase()
{
    if (client == null) { throw ex; };
    return client.GetDatabase(databaseName);
}

GetCollection -

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public IMongoCollection<T> GetCollection<T>(string collectionName)
{
    IMongoDatabase db = GetDatabase();
    IMongoCollection<T> collection = null;

    if(GetMongoDBConnectionStatus())  
    { 
        collection = db.GetCollection<T>(collectionName) 
    };
    else 
    { 
        RetryMongoHasCollection() 
    };

    return collection;
}

//Ping the database to check db connection
public bool GetMongoDBConnectionStatus()
{
    IMongoDatabase db = null;
    try
    {
        db = GetDatabase();
        var pingCommand = new BsonDocument("ping", 1;);
        var status = db.RunCommand<MongoPingStatus>(pingCommand);
        return status.ok == 1;
    }
}

//Attempt to retry connection
public bool RetryMongoHasCollection()
{
    var maxRetryCount = MongoDBSettings.maxRetryCount;
    var retryInterval = MongoDBSettings.retryInterval;
    var connected = false; int i=1;
    for (int i = 1; i < maxRetryCount; i++)
    {
        System.Threading.Thread.Sleep(retryInterval);
        if(GetMongoDBConnectionStatus())
        {
            connected = true;
            break;
        }
    }

    if (connected) { Log("Connected after x attempts")}
    else { throw ex)"Failed to Reconnect"};

    return true;
}



Comments

Popular posts from this blog

How to clear Visual Studio Cache

How to clear visual studio cache Many times, during development you would face situations where project references are not loaded properly or you get missing/error DLL's. This is because the Component cache gets corrupted randomly and without any warnings. The first option that needs to be done is to clear component cache and restart Visual Studio since the Cache might be holding onto previous DLL versions. Here are the steps on how to clear Visual Studio Cache, Clearing Component Cache: Close all Visual Studio Instances running in your machine. Also, make sure devenv.exe is not running in the Task Manager Delete the Component cache directory - %USERPROFILE%\AppData\Local\Microsoft\VisualStudio\1x.0\ComponentModelCache Restart Visual Studio The above steps should fix the cache issue most of the times, but some times that is not enough and you need to perform the below steps as well. Clearing User's Temp Folder: Open the temp folder in this locatio n -  %USERPROFILE%\AppData\Loc...

How to dependency inject to static class

.Net core supports dependency injection. There are many ways that you can inject services like constructor injection, action method injection, property injection. But there will be scenarios where you need to inject dependency services to static classes. For example, injecting services to extension methods. First, create a static class with a one property IServiceProvider type public void ConfigureServices(IServiceCollection services) { services.AddScoped<ILoggerEntry, LoggerEntry>(); services.AddTransient<IMongoRepository, MongoRepository>(); } Second, configure your services in ConfigureServices() method in Startup.cs and define the lifetime of the service instance using either Transient, Scoped or Singleton types. public void ConfigureServices(IServiceCollection services) { services.AddScoped<ILoggerEntry, LoggerEntry>(); services.AddTransient<IMongoRepository, MongoRepository>(); } For the next step to configure the Static class provider proper...

Error NU1605 - Detected package downgrade. Reference the package directly from the project to select a different version.

Error NU1605 - Detected package downgrade This error occurs when a dependency package has a version higher than an existing package version in the project solution. Solution: Add the following in .csproj file < PackageReference > < NoWarn >$( NoWarn ); NU1605 </ NoWarn > </ PackageReference > Another way to do this is to right-click on the solution and  click  Properties . Click  Build  and under  Errors and warnings  add 1605 to the  SuppressWarnings  text box. You can also add multiple error codes that you want to suppress by adding each separated by a comma. P.S. The below screenshot is in VS2019 Mac Version