Skip to content

Commit 005913c

Browse files
(GH-603) Added a new repository interception context object
1 parent 9175003 commit 005913c

File tree

6 files changed

+113
-62
lines changed

6 files changed

+113
-62
lines changed

src/DotNetToolkit.Repository/Configuration/Interceptors/IRepositoryInterceptor.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,48 +12,48 @@ public interface IRepositoryInterceptor
1212
/// An activity method which is executed when adding an entity to the repository.
1313
/// </summary>
1414
/// <typeparam name="TEntity">The type of the entity.</typeparam>
15-
/// <param name="entity">The entity.</param>
16-
void AddExecuting<TEntity>(TEntity entity);
15+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
16+
void AddExecuting<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext) where TEntity : class;
1717

1818
/// <summary>
1919
/// An activity method which is executed when deleting an entity from the repository.
2020
/// </summary>
2121
/// <typeparam name="TEntity">The type of the entity.</typeparam>
22-
/// <param name="entity">The entity.</param>
23-
void DeleteExecuting<TEntity>(TEntity entity);
22+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
23+
void DeleteExecuting<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext) where TEntity : class;
2424

2525
/// <summary>
2626
/// An activity method which is executed when updating an entity in the repository.
2727
/// </summary>
2828
/// <typeparam name="TEntity">The type of the entity.</typeparam>
29-
/// <param name="entity">The entity.</param>
30-
void UpdateExecuting<TEntity>(TEntity entity);
29+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
30+
void UpdateExecuting<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext) where TEntity : class;
3131

3232
/// <summary>
3333
/// Asynchronously an activity method which is executed when adding an entity to the repository.
3434
/// </summary>
3535
/// <typeparam name="TEntity">The type of the entity.</typeparam>
36-
/// <param name="entity">The entity.</param>
36+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
3737
/// <param name="cancellationToken">A <see cref="System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
3838
/// <returns>The <see cref="System.Threading.Tasks.Task" /> that represents the asynchronous operation.</returns>
39-
Task AddExecutingAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken());
39+
Task AddExecutingAsync<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext, CancellationToken cancellationToken = new CancellationToken()) where TEntity : class;
4040

4141
/// <summary>
4242
/// Asynchronously an activity method which is executed when deleting an entity from the repository.
4343
/// </summary>
4444
/// <typeparam name="TEntity">The type of the entity.</typeparam>
45-
/// <param name="entity">The entity.</param>
45+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
4646
/// <param name="cancellationToken">A <see cref="System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
4747
/// <returns>The <see cref="System.Threading.Tasks.Task" /> that represents the asynchronous operation.</returns>
48-
Task DeleteExecutingAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken());
48+
Task DeleteExecutingAsync<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext, CancellationToken cancellationToken = new CancellationToken()) where TEntity : class;
4949

5050
/// <summary>
5151
/// Asynchronously an activity method which is executed when updating an entity in the repository.
5252
/// </summary>
5353
/// <typeparam name="TEntity">The type of the entity.</typeparam>
54-
/// <param name="entity">The entity.</param>
54+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
5555
/// <param name="cancellationToken">A <see cref="System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
5656
/// <returns>The <see cref="System.Threading.Tasks.Task" /> that represents the asynchronous operation.</returns>
57-
Task UpdateExecutingAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken());
57+
Task UpdateExecutingAsync<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext, CancellationToken cancellationToken = new CancellationToken()) where TEntity : class;
5858
}
5959
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace DotNetToolkit.Repository.Configuration.Interceptors
2+
{
3+
using JetBrains.Annotations;
4+
using Utility;
5+
6+
/// <summary>
7+
/// Represents contextual information associated with calls into <see cref="IRepositoryInterceptor" />.
8+
/// </summary>
9+
/// <typeparam name="TEntity">The type of the entity associated to the current operation.</typeparam>
10+
public class RepositoryInterceptionContext<TEntity> where TEntity : class
11+
{
12+
/// <summary>
13+
/// Gets the entity associated with the current operation.
14+
/// </summary>
15+
public TEntity Entity { get; }
16+
17+
/// <summary>
18+
/// Gets the context.
19+
/// </summary>
20+
public IRepositoryContext Context { get; }
21+
22+
/// <summary>
23+
/// Initializes a new instance of the <see cref="RepositoryInterceptionContext{TEntity}"/> class.
24+
/// </summary>
25+
/// <param name="entity">The entity.</param>
26+
/// <param name="context">The context.</param>
27+
public RepositoryInterceptionContext([NotNull] TEntity entity, [NotNull] IRepositoryContext context)
28+
{
29+
Entity = Guard.NotNull(entity, nameof(entity));
30+
Context = Guard.NotNull(context, nameof(context));
31+
}
32+
}
33+
}

src/DotNetToolkit.Repository/Configuration/Interceptors/RepositoryInterceptorBase.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,48 +13,48 @@ public abstract class RepositoryInterceptorBase : IRepositoryInterceptor
1313
/// An activity method which is executed when adding an entity to the repository.
1414
/// </summary>
1515
/// <typeparam name="TEntity">The type of the entity.</typeparam>
16-
/// <param name="entity">The entity.</param>
17-
public virtual void AddExecuting<TEntity>(TEntity entity) { }
16+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
17+
public virtual void AddExecuting<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext) where TEntity : class {}
1818

1919
/// <summary>
2020
/// An activity method which is executed when deleting an entity from the repository.
2121
/// </summary>
2222
/// <typeparam name="TEntity">The type of the entity.</typeparam>
23-
/// <param name="entity">The entity.</param>
24-
public virtual void DeleteExecuting<TEntity>(TEntity entity) { }
23+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
24+
public virtual void DeleteExecuting<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext) where TEntity : class {}
2525

2626
/// <summary>
2727
/// An activity method which is executed when updating an entity in the repository.
2828
/// </summary>
2929
/// <typeparam name="TEntity">The type of the entity.</typeparam>
30-
/// <param name="entity">The entity.</param>
31-
public virtual void UpdateExecuting<TEntity>(TEntity entity) { }
30+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
31+
public virtual void UpdateExecuting<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext) where TEntity : class {}
3232

3333
/// <summary>
3434
/// Asynchronously an activity method which is executed when adding an entity to the repository.
3535
/// </summary>
3636
/// <typeparam name="TEntity">The type of the entity.</typeparam>
37-
/// <param name="entity">The entity.</param>
37+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
3838
/// <param name="cancellationToken">A <see cref="System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
3939
/// <returns>The <see cref="System.Threading.Tasks.Task" /> that represents the asynchronous operation.</returns>
40-
public virtual Task AddExecutingAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken()) => Task.FromResult(0);
40+
public virtual Task AddExecutingAsync<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext, CancellationToken cancellationToken = new CancellationToken()) where TEntity : class => Task.FromResult(0);
4141

4242
/// <summary>
4343
/// Asynchronously an activity method which is executed when deleting an entity from the repository.
4444
/// </summary>
4545
/// <typeparam name="TEntity">The type of the entity.</typeparam>
46-
/// <param name="entity">The entity.</param>
46+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
4747
/// <param name="cancellationToken">A <see cref="System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
4848
/// <returns>The <see cref="System.Threading.Tasks.Task" /> that represents the asynchronous operation.</returns>
49-
public virtual Task DeleteExecutingAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken()) => Task.FromResult(0);
49+
public virtual Task DeleteExecutingAsync<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext, CancellationToken cancellationToken = new CancellationToken()) where TEntity : class => Task.FromResult(0);
5050

5151
/// <summary>
5252
/// Asynchronously an activity method which is executed when updating an entity in the repository.
5353
/// </summary>
5454
/// <typeparam name="TEntity">The type of the entity.</typeparam>
55-
/// <param name="entity">The entity.</param>
55+
/// <param name="interceptionContext">The interception context which includes information for the current operation.</param>
5656
/// <param name="cancellationToken">A <see cref="System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
5757
/// <returns>The <see cref="System.Threading.Tasks.Task" /> that represents the asynchronous operation.</returns>
58-
public virtual Task UpdateExecutingAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken()) => Task.FromResult(0);
58+
public virtual Task UpdateExecutingAsync<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext, CancellationToken cancellationToken = new CancellationToken()) where TEntity : class => Task.FromResult(0);
5959
}
6060
}

src/DotNetToolkit.Repository/RepositoryBase.cs

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,10 +1430,11 @@ public void Add([NotNull] TEntity entity)
14301430

14311431
InterceptError(() => Guard.NotNull(entity, nameof(entity)));
14321432

1433-
Intercept(x => x.AddExecuting(entity));
1434-
14351433
UseContext(context =>
14361434
{
1435+
Intercept(x => x.AddExecuting(
1436+
new RepositoryInterceptionContext<TEntity>(entity, context)));
1437+
14371438
context.Add(entity);
14381439
context.SaveChanges();
14391440
});
@@ -1457,7 +1458,8 @@ public void Add([NotNull] IEnumerable<TEntity> entities)
14571458
{
14581459
foreach (var entity in entities)
14591460
{
1460-
Intercept(x => x.AddExecuting(entity));
1461+
Intercept(x => x.AddExecuting(
1462+
new RepositoryInterceptionContext<TEntity>(entity, context)));
14611463

14621464
context.Add(entity);
14631465
}
@@ -1480,10 +1482,11 @@ public void Update([NotNull] TEntity entity)
14801482

14811483
InterceptError(() => Guard.NotNull(entity, nameof(entity)));
14821484

1483-
Intercept(x => x.UpdateExecuting(entity));
1484-
14851485
UseContext(context =>
14861486
{
1487+
Intercept(x => x.UpdateExecuting(
1488+
new RepositoryInterceptionContext<TEntity>(entity, context)));
1489+
14871490
context.Update(entity);
14881491
context.SaveChanges();
14891492
});
@@ -1507,7 +1510,8 @@ public void Update([NotNull] IEnumerable<TEntity> entities)
15071510
{
15081511
foreach (var entity in entities)
15091512
{
1510-
Intercept(x => x.UpdateExecuting(entity));
1513+
Intercept(x => x.UpdateExecuting(
1514+
new RepositoryInterceptionContext<TEntity>(entity, context)));
15111515

15121516
context.Update(entity);
15131517
}
@@ -1530,10 +1534,11 @@ public void Delete([NotNull] TEntity entity)
15301534

15311535
InterceptError(() => Guard.NotNull(entity, nameof(entity)));
15321536

1533-
Intercept(x => x.DeleteExecuting(entity));
1534-
15351537
UseContext(context =>
15361538
{
1539+
Intercept(x => x.DeleteExecuting(
1540+
new RepositoryInterceptionContext<TEntity>(entity, context)));
1541+
15371542
context.Remove(entity);
15381543
context.SaveChanges();
15391544
});
@@ -1591,7 +1596,8 @@ public void Delete([NotNull] IEnumerable<TEntity> entities)
15911596
{
15921597
foreach (var entity in entities)
15931598
{
1594-
Intercept(x => x.DeleteExecuting(entity));
1599+
Intercept(x => x.DeleteExecuting(
1600+
new RepositoryInterceptionContext<TEntity>(entity, context)));
15951601

15961602
context.Remove(entity);
15971603
}
@@ -2175,10 +2181,12 @@ Task<int> Getter() =>
21752181
cancellationToken.ThrowIfCancellationRequested();
21762182
});
21772183

2178-
await InterceptAsync(x => x.AddExecutingAsync(entity, cancellationToken));
2179-
21802184
await UseContextAsync(async context =>
21812185
{
2186+
await InterceptAsync(x => x.AddExecutingAsync(
2187+
new RepositoryInterceptionContext<TEntity>(entity, context),
2188+
cancellationToken));
2189+
21822190
context.Add(entity);
21832191
await context.SaveChangesAsync(cancellationToken);
21842192
});
@@ -2209,7 +2217,9 @@ await UseContextAsync(async context =>
22092217
{
22102218
foreach (var entity in entities)
22112219
{
2212-
await InterceptAsync(x => x.AddExecutingAsync(entity, cancellationToken));
2220+
await InterceptAsync(x => x.AddExecutingAsync(
2221+
new RepositoryInterceptionContext<TEntity>(entity, context),
2222+
cancellationToken));
22132223

22142224
context.Add(entity);
22152225
}
@@ -2239,10 +2249,12 @@ await UseContextAsync(async context =>
22392249
cancellationToken.ThrowIfCancellationRequested();
22402250
});
22412251

2242-
await InterceptAsync(x => x.UpdateExecutingAsync(entity, cancellationToken));
2243-
22442252
await UseContextAsync(async context =>
22452253
{
2254+
await InterceptAsync(x => x.UpdateExecutingAsync(
2255+
new RepositoryInterceptionContext<TEntity>(entity, context),
2256+
cancellationToken));
2257+
22462258
context.Update(entity);
22472259
await context.SaveChangesAsync(cancellationToken);
22482260
});
@@ -2273,7 +2285,9 @@ await UseContextAsync(async context =>
22732285
{
22742286
foreach (var entity in entities)
22752287
{
2276-
await InterceptAsync(x => x.UpdateExecutingAsync(entity, cancellationToken));
2288+
await InterceptAsync(x => x.UpdateExecutingAsync(
2289+
new RepositoryInterceptionContext<TEntity>(entity, context),
2290+
cancellationToken));
22772291

22782292
context.Update(entity);
22792293
}
@@ -2303,10 +2317,12 @@ await UseContextAsync(async context =>
23032317
cancellationToken.ThrowIfCancellationRequested();
23042318
});
23052319

2306-
await InterceptAsync(x => x.DeleteExecutingAsync(entity, cancellationToken));
2307-
23082320
await UseContextAsync(async context =>
23092321
{
2322+
await InterceptAsync(x => x.DeleteExecutingAsync(
2323+
new RepositoryInterceptionContext<TEntity>(entity, context),
2324+
cancellationToken));
2325+
23102326
context.Remove(entity);
23112327
await context.SaveChangesAsync(cancellationToken);
23122328
});
@@ -2377,7 +2393,9 @@ await UseContextAsync(async context =>
23772393
{
23782394
foreach (var entity in entities)
23792395
{
2380-
await InterceptAsync(x => x.DeleteExecutingAsync(entity, cancellationToken));
2396+
await InterceptAsync(x => x.DeleteExecutingAsync(
2397+
new RepositoryInterceptionContext<TEntity>(entity, context),
2398+
cancellationToken));
23812399

23822400
context.Remove(entity);
23832401
}

test/DotNetToolkit.Repository.Integration.Test/Data/TestRepositoryTimeStampInterceptor.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ public TestRepositoryTimeStampInterceptor(string loggedInUser)
2323
_user = loggedInUser;
2424
}
2525

26-
public override void AddExecuting<TEntity>(TEntity entity)
26+
public override void AddExecuting<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext)
2727
{
28-
if (entity is IHaveTimeStamp haveStamp)
28+
if (interceptionContext.Entity is IHaveTimeStamp haveStamp)
2929
{
3030
var currentTime = DateTime.UtcNow;
3131

@@ -36,9 +36,9 @@ public override void AddExecuting<TEntity>(TEntity entity)
3636
}
3737
}
3838

39-
public override void UpdateExecuting<TEntity>(TEntity entity)
39+
public override void UpdateExecuting<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext)
4040
{
41-
if (entity is IHaveTimeStamp haveStamp)
41+
if (interceptionContext.Entity is IHaveTimeStamp haveStamp)
4242
{
4343
var currentTime = DateTime.UtcNow;
4444

@@ -47,9 +47,9 @@ public override void UpdateExecuting<TEntity>(TEntity entity)
4747
}
4848
}
4949

50-
public override Task AddExecutingAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken())
50+
public override Task AddExecutingAsync<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext, CancellationToken cancellationToken = new CancellationToken())
5151
{
52-
if (entity is IHaveTimeStamp haveStamp)
52+
if (interceptionContext.Entity is IHaveTimeStamp haveStamp)
5353
{
5454
var currentTime = DateTime.UtcNow;
5555

@@ -62,9 +62,9 @@ public override void UpdateExecuting<TEntity>(TEntity entity)
6262
return Task.FromResult(0);
6363
}
6464

65-
public override Task UpdateExecutingAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken())
65+
public override Task UpdateExecutingAsync<TEntity>(RepositoryInterceptionContext<TEntity> interceptionContext, CancellationToken cancellationToken = new CancellationToken())
6666
{
67-
if (entity is IHaveTimeStamp haveStamp)
67+
if (interceptionContext.Entity is IHaveTimeStamp haveStamp)
6868
{
6969
var currentTime = DateTime.UtcNow;
7070

0 commit comments

Comments
 (0)