Skip to content

Commit

Permalink
Create MongoDbContext which provides the IMongoDatabase to other cont…
Browse files Browse the repository at this point in the history
…exts.

Make it a scoped service so only 1 MongoClient is created per request. Use that to expose transactions which are now shared across all Repos.
  • Loading branch information
hahn-kev committed Sep 27, 2024
1 parent 2184716 commit 8afdcd8
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 76 deletions.
10 changes: 4 additions & 6 deletions Backend/Contexts/BannerContext.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class BannerContext : IBannerContext
{
private readonly IMongoDatabase _db;
private readonly IMongoDbContext _mongoDbContext;

public BannerContext(IOptions<Startup.Settings> options)
public BannerContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<Banner> Banners => _db.GetCollection<Banner>("BannerCollection");
public IMongoCollection<Banner> Banners => _mongoDbContext.Db.GetCollection<Banner>("BannerCollection");
}
}
11 changes: 4 additions & 7 deletions Backend/Contexts/MergeBlacklistContext.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class MergeBlacklistContext : IMergeBlacklistContext
{
private readonly IMongoDatabase _db;

public MergeBlacklistContext(IOptions<Startup.Settings> options)
private readonly IMongoDbContext _mongoDbContext;
public MergeBlacklistContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<MergeWordSet> MergeBlacklist => _db.GetCollection<MergeWordSet>(
public IMongoCollection<MergeWordSet> MergeBlacklist => _mongoDbContext.Db.GetCollection<MergeWordSet>(
"MergeBlacklistCollection");
}
}
11 changes: 4 additions & 7 deletions Backend/Contexts/MergeGraylistContext.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class MergeGraylistContext : IMergeGraylistContext
{
private readonly IMongoDatabase _db;

public MergeGraylistContext(IOptions<Startup.Settings> options)
private readonly IMongoDbContext _mongoDbContext;
public MergeGraylistContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<MergeWordSet> MergeGraylist => _db.GetCollection<MergeWordSet>(
public IMongoCollection<MergeWordSet> MergeGraylist => _mongoDbContext.Db.GetCollection<MergeWordSet>(
"MergeGraylistCollection");
}
}
47 changes: 47 additions & 0 deletions Backend/Contexts/MongoDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Threading.Tasks;
using BackendFramework.Interfaces;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts;

public class MongoDbContext : IMongoDbContext
{
public IMongoDatabase Db { get; }

public MongoDbContext(IOptions<Startup.Settings> options)
{
var client = new MongoClient(options.Value.ConnectionString);
Db = client.GetDatabase(options.Value.CombineDatabase);
}

public async Task<IMongoTransaction> BeginTransaction()
{
return new MongoTransactionWrapper(await Db.Client.StartSessionAsync());
}

private class MongoTransactionWrapper : IMongoTransaction
{
private readonly IClientSessionHandle _session;

public MongoTransactionWrapper(IClientSessionHandle session)
{
_session = session;
}

public Task CommitTransactionAsync()
{
return _session.CommitTransactionAsync();
}

public Task AbortTransactionAsync()
{
return _session.AbortTransactionAsync();
}

public void Dispose()
{
_session.Dispose();
}
}
}
9 changes: 4 additions & 5 deletions Backend/Contexts/PasswordResetContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@ namespace BackendFramework.Contexts
[ExcludeFromCodeCoverage]
public class PasswordResetContext : IPasswordResetContext
{
private readonly IMongoDatabase _db;
private readonly IMongoDbContext _mongoDbContext;
public int ExpireTime { get; }

public PasswordResetContext(IOptions<Startup.Settings> options)
public PasswordResetContext(IOptions<Startup.Settings> options, IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
ExpireTime = options.Value.PassResetExpireTime;
}

private IMongoCollection<PasswordReset> PasswordResets => _db.GetCollection<PasswordReset>(
private IMongoCollection<PasswordReset> PasswordResets => _mongoDbContext.Db.GetCollection<PasswordReset>(
"PasswordResetCollection");

public Task ClearAll(string email)
Expand Down
11 changes: 4 additions & 7 deletions Backend/Contexts/ProjectContext.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class ProjectContext : IProjectContext
{
private readonly IMongoDatabase _db;

public ProjectContext(IOptions<Startup.Settings> options)
private readonly IMongoDbContext _mongoDbContext;
public ProjectContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<Project> Projects => _db.GetCollection<Project>("ProjectsCollection");
public IMongoCollection<Project> Projects => _mongoDbContext.Db.GetCollection<Project>("ProjectsCollection");
}
}
13 changes: 5 additions & 8 deletions Backend/Contexts/SemanticDomainContext.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class SemanticDomainContext : ISemanticDomainContext
{
private readonly IMongoDatabase _db;

public SemanticDomainContext(IOptions<Startup.Settings> options)
private readonly IMongoDbContext _mongoDbContext;
public SemanticDomainContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<SemanticDomainTreeNode> SemanticDomains => _db.GetCollection<SemanticDomainTreeNode>("SemanticDomainTree");
public IMongoCollection<SemanticDomainFull> FullSemanticDomains => _db.GetCollection<SemanticDomainFull>("SemanticDomains");
public IMongoCollection<SemanticDomainTreeNode> SemanticDomains => _mongoDbContext.Db.GetCollection<SemanticDomainTreeNode>("SemanticDomainTree");
public IMongoCollection<SemanticDomainFull> FullSemanticDomains => _mongoDbContext.Db.GetCollection<SemanticDomainFull>("SemanticDomains");
}
}
12 changes: 5 additions & 7 deletions Backend/Contexts/SpeakerContext.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class SpeakerContext : ISpeakerContext
{
private readonly IMongoDatabase _db;

public SpeakerContext(IOptions<Startup.Settings> options)
private readonly IMongoDbContext _mongoDbContext;
public SpeakerContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<Speaker> Speakers => _db.GetCollection<Speaker>("SpeakersCollection");
public IMongoCollection<Speaker> Speakers => _mongoDbContext.Db.GetCollection<Speaker>("SpeakersCollection");
}
}
11 changes: 4 additions & 7 deletions Backend/Contexts/UserContext.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class UserContext : IUserContext
{
private readonly IMongoDatabase _db;

public UserContext(IOptions<Startup.Settings> options)
private readonly IMongoDbContext _mongoDbContext;
public UserContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<User> Users => _db.GetCollection<User>("UsersCollection");
public IMongoCollection<User> Users => _mongoDbContext.Db.GetCollection<User>("UsersCollection");
}
}
11 changes: 4 additions & 7 deletions Backend/Contexts/UserEditContext.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class UserEditContext : IUserEditContext
{
private readonly IMongoDatabase _db;

public UserEditContext(IOptions<Startup.Settings> options)
private readonly IMongoDbContext _mongoDbContext;
public UserEditContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<UserEdit> UserEdits => _db.GetCollection<UserEdit>("UserEditsCollection");
public IMongoCollection<UserEdit> UserEdits => _mongoDbContext.Db.GetCollection<UserEdit>("UserEditsCollection");
}
}
11 changes: 4 additions & 7 deletions Backend/Contexts/UserRoleContext.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class UserRoleContext : IUserRoleContext
{
private readonly IMongoDatabase _db;

public UserRoleContext(IOptions<Startup.Settings> options)
private readonly IMongoDbContext _mongoDbContext;
public UserRoleContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<UserRole> UserRoles => _db.GetCollection<UserRole>("UserRolesCollection");
public IMongoCollection<UserRole> UserRoles => _mongoDbContext.Db.GetCollection<UserRole>("UserRolesCollection");
}
}
13 changes: 5 additions & 8 deletions Backend/Contexts/WordContext.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace BackendFramework.Contexts
{
[ExcludeFromCodeCoverage]
public class WordContext : IWordContext
{
private readonly IMongoDatabase _db;

public WordContext(IOptions<Startup.Settings> options)
private readonly IMongoDbContext _mongoDbContext;
public WordContext(IMongoDbContext mongoDbContext)
{
var client = new MongoClient(options.Value.ConnectionString);
_db = client.GetDatabase(options.Value.CombineDatabase);
_mongoDbContext = mongoDbContext;
}

public IMongoCollection<Word> Words => _db.GetCollection<Word>("WordsCollection");
public IMongoCollection<Word> Frontier => _db.GetCollection<Word>("FrontierCollection");
public IMongoCollection<Word> Words => _mongoDbContext.Db.GetCollection<Word>("WordsCollection");
public IMongoCollection<Word> Frontier => _mongoDbContext.Db.GetCollection<Word>("FrontierCollection");
}
}
17 changes: 17 additions & 0 deletions Backend/Interfaces/IMongoDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Threading.Tasks;
using MongoDB.Driver;

namespace BackendFramework.Interfaces;

public interface IMongoDbContext
{
IMongoDatabase Db { get; }
Task<IMongoTransaction> BeginTransaction();
}

public interface IMongoTransaction : IDisposable
{
Task CommitTransactionAsync();
Task AbortTransactionAsync();
}
3 changes: 3 additions & 0 deletions Backend/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ public void ConfigureServices(IServiceCollection services)
services.AddTransient<IWordContext, WordContext>();
services.AddTransient<IWordRepository, WordRepository>();
services.AddTransient<IWordService, WordService>();

// mongo context, scoped so it is shared across a single request
services.AddScoped<IMongoDbContext, MongoDbContext>();
}

/// <summary> This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down

0 comments on commit 8afdcd8

Please sign in to comment.