db: refactor to only init mongo client & collections once

This commit is contained in:
Abdullah Atta
2024-06-07 15:39:12 +05:00
parent c5b41be2fd
commit 99f095babe
4 changed files with 23 additions and 57 deletions

View File

@@ -28,20 +28,26 @@ using System.Threading.Tasks;
namespace Streetwriters.Data.DbContexts
{
public class MongoDbContext : IDbContext
public class MongoDbContext(IMongoClient MongoClient) : IDbContext
{
private IMongoDatabase Database { get; set; }
private MongoClient MongoClient { get; set; }
private readonly List<Func<IClientSessionHandle, CancellationToken, Task>> _commands;
private IDbSettings DbSettings { get; set; }
public MongoDbContext(IDbSettings dbSettings)
public static IMongoClient CreateMongoDbClient(IDbSettings dbSettings)
{
DbSettings = dbSettings;
Configure();
// Every command will be stored and it'll be processed at SaveChanges
_commands = new List<Func<IClientSessionHandle, CancellationToken, Task>>();
var settings = MongoClientSettings.FromConnectionString(dbSettings.ConnectionString);
settings.MaxConnectionPoolSize = 500;
settings.MinConnectionPoolSize = 0;
return new MongoClient(settings);
}
public static IMongoCollection<T> GetMongoCollection<T>(IMongoClient client, string databaseName, string collectionName)
{
return client.GetDatabase(databaseName).GetCollection<T>(collectionName, new MongoCollectionSettings()
{
AssignIdOnInsert = true,
});
}
private readonly List<Func<IClientSessionHandle, CancellationToken, Task>> _commands = [];
public async Task<int> SaveChanges()
{
try
@@ -51,7 +57,7 @@ namespace Streetwriters.Data.DbContexts
using (IClientSessionHandle session = await MongoClient.StartSessionAsync())
{
#if DEBUG
await Task.WhenAll(_commands.Select(c => c(session, default)));
await Parallel.ForEachAsync(_commands, async (c, ct) => await c(session, ct));
#else
await session.WithTransactionAsync(async (handle, token) =>
{
@@ -71,26 +77,6 @@ namespace Streetwriters.Data.DbContexts
}
}
private void Configure()
{
if (MongoClient != null)
{
return;
}
var settings = MongoClientSettings.FromConnectionString(DbSettings.ConnectionString);
settings.MaxConnectionPoolSize = 500;
settings.MinConnectionPoolSize = 0;
MongoClient = new MongoClient(settings);
}
public IMongoCollection<T> GetCollection<T>(string databaseName, string collectionName)
{
return MongoClient.GetDatabase(databaseName).GetCollection<T>(collectionName, new MongoCollectionSettings()
{
AssignIdOnInsert = true,
});
}
public void AddCommand(Func<IClientSessionHandle, CancellationToken, Task> func)
{
_commands.Add(func);
@@ -100,10 +86,5 @@ namespace Streetwriters.Data.DbContexts
{
GC.SuppressFinalize(this);
}
public Task DropDatabaseAsync()
{
return MongoClient.DropDatabaseAsync(DbSettings.DatabaseName);
}
}
}

View File

@@ -29,6 +29,5 @@ namespace Streetwriters.Data.Interfaces
{
void AddCommand(Func<IClientSessionHandle, CancellationToken, Task> func);
Task<int> SaveChanges();
IMongoCollection<T> GetCollection<T>(string databaseName, string collectionName);
}
}

View File

@@ -31,20 +31,14 @@ namespace Streetwriters.Data.Repositories
public class Repository<TEntity> where TEntity : class
{
protected readonly IDbContext dbContext;
protected IMongoCollection<TEntity> Collection { get; set; }
public IMongoCollection<TEntity> Collection { get; set; }
public Repository(IDbContext _dbContext, string databaseName, string collectionName)
public Repository(IDbContext _dbContext, IMongoCollection<TEntity> collection)
{
dbContext = _dbContext;
Collection = GetCollection(databaseName, collectionName);
Collection = collection;
}
private protected IMongoCollection<TEntity> GetCollection(string databaseName, string collectionName)
{
return dbContext.GetCollection<TEntity>(databaseName, collectionName);
}
public virtual void Insert(TEntity obj)
{
dbContext.AddCommand((handle, ct) => Collection.InsertOneAsync(handle, obj, null, ct));

View File

@@ -23,24 +23,16 @@ using Streetwriters.Data.Interfaces;
namespace Streetwriters.Data
{
public class UnitOfWork : IUnitOfWork
public class UnitOfWork(IDbContext dbContext) : IUnitOfWork
{
private readonly IDbContext dbContext;
public UnitOfWork(IDbContext _dbContext)
{
dbContext = _dbContext;
}
public async Task<bool> Commit()
{
var changeAmount = await dbContext.SaveChanges();
return changeAmount > 0;
return await dbContext.SaveChanges() > 0;
}
public void Dispose()
{
this.dbContext.Dispose();
dbContext.Dispose();
}
}
}