File tree Expand file tree Collapse file tree 5 files changed +35
-4
lines changed
CodeOfChaos.Types.UnitOfWork.Contracts
CodeOfChaos.Types.UnitOfWork
tests/Tests.CodeOfChaos.Types.UnitOfWork Expand file tree Collapse file tree 5 files changed +35
-4
lines changed Original file line number Diff line number Diff line change @@ -20,5 +20,5 @@ public interface IUnitOfWork : IAsyncDisposable {
2020
2121 ValueTask < TDbContext > GetDbContextAsync < TDbContext > ( CancellationToken ct = default ) where TDbContext : DbContext ;
2222
23- TRepo GetRepository < TRepo > ( ) where TRepo : class , IUnitOfWorkRepository ;
23+ ValueTask < TRepo > GetRepositoryAsync < TRepo > ( CancellationToken ct = default ) where TRepo : class , IUnitOfWorkRepository ;
2424}
Original file line number Diff line number Diff line change @@ -5,4 +5,5 @@ namespace CodeOfChaos.Types.UnitOfWork;
55// ---------------------------------------------------------------------------------------------------------------------
66// Code
77// ---------------------------------------------------------------------------------------------------------------------
8- public interface IUnitOfWorkRepository ;
8+ public interface IUnitOfWorkRepository {
9+ }
Original file line number Diff line number Diff line change @@ -84,11 +84,13 @@ public virtual async ValueTask<T> GetDbContextAsync<T>(CancellationToken ct = de
8484 return dbContext as T ?? throw new InvalidCastException ( $ "Cannot cast DbContext of type '{ dbContext . GetType ( ) } ' to '{ typeof ( T ) } '") ;
8585 }
8686
87- public virtual TRepo GetRepository < TRepo > ( ) where TRepo : class , IUnitOfWorkRepository {
87+ public virtual async ValueTask < TRepo > GetRepositoryAsync < TRepo > ( CancellationToken ct = default ) where TRepo : class , IUnitOfWorkRepository {
8888 if ( AttachedRepositories . TryGetValue ( typeof ( TRepo ) , out IUnitOfWorkRepository ? cachedRepo ) && cachedRepo is TRepo castedCachedRepo ) return castedCachedRepo ;
8989
9090 // Cache miss so we create a new instance
9191 var repo = serviceScope . ServiceProvider . GetRequiredService < TRepo > ( ) ;
92+ if ( repo is not UnitOfWorkRepository < TDbContext > castedRepo ) throw new InvalidCastException ( $ "Cannot cast repository of type '{ repo . GetType ( ) } ' to '{ typeof ( TRepo ) } '") ;
93+ await castedRepo . AttachAsync ( this , ct ) ;
9294
9395 AttachedRepositories . AddOrUpdate ( typeof ( TRepo ) , repo ) ;
9496 return repo ;
@@ -98,6 +100,10 @@ public virtual async ValueTask DisposeAsync() {
98100 if ( _transaction != null ) await TryRollbackTransactionAsync ( ) ;
99101
100102 if ( ! AttachedRepositories . IsEmpty ) {
103+ foreach ( IUnitOfWorkRepository repository in AttachedRepositories . Values ) {
104+ if ( repository is not UnitOfWorkRepository < TDbContext > castedRepo ) continue ;
105+ castedRepo . Detach ( ) ;
106+ }
101107 AttachedRepositories . Clear ( ) ;
102108 }
103109
Original file line number Diff line number Diff line change 1+ // ---------------------------------------------------------------------------------------------------------------------
2+ // Imports
3+ // ---------------------------------------------------------------------------------------------------------------------
4+ using Microsoft . EntityFrameworkCore ;
5+
6+ namespace CodeOfChaos . Types . UnitOfWork ;
7+
8+ // ---------------------------------------------------------------------------------------------------------------------
9+ // Code
10+ // ---------------------------------------------------------------------------------------------------------------------
11+ public abstract class UnitOfWorkRepository < TDbContext > : IUnitOfWorkRepository
12+ where TDbContext : DbContext
13+ {
14+ private TDbContext ? DbContext { get ; set ; }
15+
16+ // -----------------------------------------------------------------------------------------------------------------
17+ // Methods
18+ // -----------------------------------------------------------------------------------------------------------------
19+ internal async ValueTask AttachAsync ( IUnitOfWork unitOfWork , CancellationToken ct = default ) => DbContext = await unitOfWork . GetDbContextAsync < TDbContext > ( ct ) ;
20+ internal void Detach ( ) => DbContext = null ; // Remove the reference to the DbContext
21+
22+ protected TDbContext GetDbContext ( ) => DbContext ?? throw new InvalidOperationException ( "Repository is not attached to a UnitOfWork." ) ;
23+ protected DbSet < TModel > GetDbSet < TModel > ( ) where TModel : class => DbContext ? . Set < TModel > ( ) ?? throw new InvalidOperationException ( "Repository is not attached to a UnitOfWork." ) ;
24+ }
Original file line number Diff line number Diff line change @@ -200,7 +200,7 @@ public async Task GetRepository_ShouldRetrieveRepositoryFromServiceProvider() {
200200
201201
202202 // Act
203- var repository = _unitOfWork . GetRepository < IUnitOfWorkRepository > ( ) ;
203+ var repository = await _unitOfWork . GetRepositoryAsync < IUnitOfWorkRepository > ( ) ;
204204
205205 // Assert
206206 await Assert . That ( repository ) . IsNotNull ( ) ;
You can’t perform that action at this time.
0 commit comments