Skip to content

Commit afd6b50

Browse files
committed
Feat: GetCachedDbSet
1 parent 5e61089 commit afd6b50

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

src/CodeOfChaos.Types.UnitOfWork.Contracts/IUnitOfWorkRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ namespace CodeOfChaos.Types.UnitOfWork;
55
// ---------------------------------------------------------------------------------------------------------------------
66
// Code
77
// ---------------------------------------------------------------------------------------------------------------------
8-
public interface IUnitOfWorkRepository {}
8+
public interface IUnitOfWorkRepository;

src/CodeOfChaos.Types.UnitOfWork/UnitOfWork.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,17 @@ public virtual async ValueTask<TRepo> GetRepositoryAsync<TRepo>(CancellationToke
8787
if (AttachedRepositories.TryGetValue(typeof(TRepo), out IUnitOfWorkRepository? cachedRepo) && cachedRepo is TRepo castedCachedRepo) return castedCachedRepo;
8888

8989
// Cache miss so we create a new instance
90+
var repo = await CreateAndAttachRepositoryAsync<TRepo>(ct);
91+
92+
AttachedRepositories.AddOrUpdate(typeof(TRepo), repo);
93+
return repo;
94+
}
95+
96+
public virtual async ValueTask<TRepo> CreateAndAttachRepositoryAsync<TRepo>(CancellationToken ct = default) where TRepo : class, IUnitOfWorkRepository {
9097
var repo = serviceScope.ServiceProvider.GetRequiredService<TRepo>();
9198
if (repo is not UnitOfWorkRepository<TDbContext> castedRepo) throw new InvalidCastException($"Cannot cast repository of type '{repo.GetType()}' to '{typeof(TRepo)}'");
9299

93100
await castedRepo.AttachAsync(this, ct);
94-
95-
AttachedRepositories.AddOrUpdate(typeof(TRepo), repo);
96101
return repo;
97102
}
98103

src/CodeOfChaos.Types.UnitOfWork/UnitOfWorkRepository.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Imports
33
// ---------------------------------------------------------------------------------------------------------------------
44
using Microsoft.EntityFrameworkCore;
5+
using System.Collections.Concurrent;
56

67
namespace CodeOfChaos.Types.UnitOfWork;
78
// ---------------------------------------------------------------------------------------------------------------------
@@ -10,6 +11,7 @@ namespace CodeOfChaos.Types.UnitOfWork;
1011
public abstract class UnitOfWorkRepository<TDbContext> : IUnitOfWorkRepository
1112
where TDbContext : DbContext {
1213
private TDbContext? DbContext { get; set; }
14+
private ConcurrentDictionary<Type,object> DbSetCache {get;} = new();
1315

1416
// -----------------------------------------------------------------------------------------------------------------
1517
// Methods
@@ -18,5 +20,11 @@ public abstract class UnitOfWorkRepository<TDbContext> : IUnitOfWorkRepository
1820
internal void Detach() => DbContext = null;// Remove the reference to the DbContext
1921

2022
protected TDbContext GetDbContext() => DbContext ?? throw new InvalidOperationException("Repository is not attached to a UnitOfWork.");
21-
protected DbSet<TModel> GetDbSet<TModel>() where TModel : class => DbContext?.Set<TModel>() ?? throw new InvalidOperationException("Repository is not attached to a UnitOfWork.");
23+
protected DbSet<TModel> GetDbSet<TModel>() where TModel : class => GetDbContext().Set<TModel>();
24+
protected DbSet<TModel> GetCachedDbSet<TModel>() where TModel : class
25+
=> (DbSet<TModel>)DbSetCache.GetOrAdd(
26+
typeof(TModel),
27+
static (_, dbContext) => dbContext.Set<TModel>(),
28+
GetDbContext()
29+
);
2230
}

0 commit comments

Comments
 (0)