@@ -15,16 +15,53 @@ public sealed class DomainEventsToOutboxMessageSaveChangesInterceptor(TimeProvid
1515{
1616 private readonly TimeProvider _timeProvider = timeProvider ;
1717
18+ /// <summary>
19+ /// Captures domain events from tracked aggregate roots and stores them as outbox messages before persisting changes.
20+ /// </summary>
21+ public override InterceptionResult < int > SavingChanges ( DbContextEventData eventData , InterceptionResult < int > result )
22+ {
23+ CaptureDomainEvents ( eventData . Context ) ;
24+ return result ;
25+ }
26+
1827 /// <summary>
1928 /// Captures domain events from tracked aggregate roots and stores them as outbox messages before persisting changes.
2029 /// </summary>
2130 public override ValueTask < InterceptionResult < int > > SavingChangesAsync ( DbContextEventData eventData , InterceptionResult < int > result , CancellationToken cancellationToken = default )
2231 {
23- var dbContext = eventData . Context ;
32+ CaptureDomainEvents ( eventData . Context ) ;
33+ return base . SavingChangesAsync ( eventData , result , cancellationToken ) ;
34+ }
35+
36+ /// <summary>
37+ /// Wakes the outbox relay after a save that committed outside an explicit transaction, so domain events captured
38+ /// by a bare <c>SaveChanges</c> are relayed promptly instead of waiting for the next poll. When a transaction is
39+ /// open the relay is signalled on commit by the transaction-commit interceptor instead, so this skips that case to
40+ /// avoid waking the relay before the rows are committed and visible.
41+ /// </summary>
42+ public override int SavedChanges ( SaveChangesCompletedEventData eventData , int result )
43+ {
44+ WakeRelayIfNeeded ( eventData . Context ) ;
45+ return result ;
46+ }
47+
48+ /// <summary>
49+ /// Wakes the outbox relay after a save that committed outside an explicit transaction, so domain events captured
50+ /// by a bare <c>SaveChanges</c> are relayed promptly instead of waiting for the next poll. When a transaction is
51+ /// open the relay is signalled on commit by the transaction-commit interceptor instead, so this skips that case to
52+ /// avoid waking the relay before the rows are committed and visible.
53+ /// </summary>
54+ public override ValueTask < int > SavedChangesAsync ( SaveChangesCompletedEventData eventData , int result , CancellationToken cancellationToken = default )
55+ {
56+ WakeRelayIfNeeded ( eventData . Context ) ;
57+ return base . SavedChangesAsync ( eventData , result , cancellationToken ) ;
58+ }
2459
60+ private void CaptureDomainEvents ( DbContext ? dbContext )
61+ {
2562 if ( dbContext is not ISaveOutboxMessages dbContextWithOutboxMessages )
2663 {
27- return base . SavingChangesAsync ( eventData , result , cancellationToken ) ;
64+ return ;
2865 }
2966
3067 Activity ? activity = null ;
@@ -55,24 +92,14 @@ public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextE
5592 } ) . ToList ( ) ;
5693
5794 dbContextWithOutboxMessages . OutboxMessages . AddRange ( outboxMessages ) ;
58-
59- return base . SavingChangesAsync ( eventData , result , cancellationToken ) ;
6095 }
6196
62- /// <summary>
63- /// Wakes the outbox relay after a save that committed outside an explicit transaction, so domain events captured
64- /// by a bare <c>SaveChanges</c> are relayed promptly instead of waiting for the next poll. When a transaction is
65- /// open the relay is signalled on commit by the transaction-commit interceptor instead, so this skips that case to
66- /// avoid waking the relay before the rows are committed and visible.
67- /// </summary>
68- public override ValueTask < int > SavedChangesAsync ( SaveChangesCompletedEventData eventData , int result , CancellationToken cancellationToken = default )
97+ private void WakeRelayIfNeeded ( DbContext ? dbContext )
6998 {
70- if ( ShouldWakeRelay ( eventData . Context ) )
99+ if ( ShouldWakeRelay ( dbContext ) )
71100 {
72101 signal . Notify ( ) ;
73102 }
74-
75- return base . SavedChangesAsync ( eventData , result , cancellationToken ) ;
76103 }
77104
78105 private static bool ShouldWakeRelay ( DbContext ? dbContext ) =>
0 commit comments