Skip to content

Commit fedcc5f

Browse files
committed
PropertyForwardingInterceptor -> DirectiveInterceptor
1 parent 2cbd496 commit fedcc5f

11 files changed

Lines changed: 161 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace BitzArt.CA.Persistence;
4+
5+
internal class DirectiveInterceptorConfigurationBuilder<TEntity>
6+
(DirectiveInterceptor<TEntity> interceptor)
7+
: IDirectiveInterceptorConfigurationBuilder<TEntity>
8+
where TEntity : class
9+
{
10+
DirectiveInterceptor<TEntity> IDirectiveInterceptorConfigurationBuilder<TEntity>.Interceptor => interceptor;
11+
12+
public IDirectiveInterceptorForwardingRuleBuilder<TEntity, TProperty> Forward<TProperty>(Func<DbContext, TEntity, TProperty> originValueGetter)
13+
=> new DirectiveInterceptorForwardingRuleBuilder<TEntity, TProperty>(this, originValueGetter);
14+
15+
public IDirectiveInterceptorConfigurationBuilder<TEntity> Invoke(Action<DbContext, TEntity> action)
16+
{
17+
interceptor.AddDirective(action);
18+
return this;
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace BitzArt.CA.Persistence;
4+
5+
internal class DirectiveInterceptorForwardingRuleBuilder<TEntity, TProperty>
6+
(IDirectiveInterceptorConfigurationBuilder<TEntity> builder, Func<DbContext, TEntity, TProperty> originValueGetter)
7+
: IDirectiveInterceptorForwardingRuleBuilder<TEntity, TProperty>
8+
where TEntity : class
9+
{
10+
public IDirectiveInterceptorConfigurationBuilder<TEntity> To(Action<DbContext, TEntity, TProperty> targetValueSetter)
11+
{
12+
builder.Interceptor.AddDirective((dbContext, entity) =>
13+
{
14+
var value = originValueGetter.Invoke(dbContext, entity);
15+
targetValueSetter.Invoke(dbContext, entity, value);
16+
});
17+
return builder;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace BitzArt.CA.Persistence;
4+
5+
/// <summary>
6+
/// Builder for configuring property forwarding rules.
7+
/// </summary>
8+
/// <typeparam name="TEntity">Entity type.</typeparam>
9+
public interface IDirectiveInterceptorConfigurationBuilder<TEntity>
10+
where TEntity : class
11+
{
12+
internal DirectiveInterceptor<TEntity> Interceptor { get; }
13+
14+
/// <inheritdoc/>
15+
public IDirectiveInterceptorForwardingRuleBuilder<TEntity, object> Forward(string propertyName)
16+
=> Forward<object>(propertyName);
17+
18+
/// <summary>
19+
/// Specifies the source property from which the value will be forwarded.
20+
/// </summary>
21+
/// <typeparam name="TProperty">Property type.</typeparam>
22+
/// <param name="propertyName">Name of the property to get the value from.</param>
23+
/// <returns><see cref="IDirectiveInterceptorForwardingRuleBuilder{TEntity, TProperty}"/> for further configuration.</returns>
24+
public IDirectiveInterceptorForwardingRuleBuilder<TEntity, TProperty> Forward<TProperty>(string propertyName)
25+
=> Forward((dbContext, entity) =>
26+
{
27+
var entry = dbContext.Entry(entity);
28+
var property = entry.Property<TProperty>(propertyName);
29+
return property.CurrentValue;
30+
});
31+
32+
/// <inheritdoc cref="Forward{TProperty}(Func{DbContext, TEntity, TProperty})"/>
33+
public IDirectiveInterceptorForwardingRuleBuilder<TEntity, TProperty> Forward<TProperty>(Func<TEntity, TProperty> originValueGetter)
34+
=> Forward((_, entity) => originValueGetter(entity));
35+
36+
/// <summary>
37+
/// Specifies the source property from which the value will be forwarded.
38+
/// </summary>
39+
/// <typeparam name="TProperty">Property type.</typeparam>
40+
/// <param name="originValueGetter">Function to get the value from the source property.</param>
41+
/// <returns><see cref="IDirectiveInterceptorForwardingRuleBuilder{TEntity, TProperty}"/> for further configuration.</returns>
42+
public IDirectiveInterceptorForwardingRuleBuilder<TEntity, TProperty> Forward<TProperty>(Func<DbContext, TEntity, TProperty> originValueGetter);
43+
44+
/// <inheritdoc cref="Invoke(Action{DbContext, TEntity})"/>
45+
public IDirectiveInterceptorConfigurationBuilder<TEntity> Invoke(Action<TEntity> action)
46+
=> Invoke((_, entity) => action(entity));
47+
48+
/// <summary>
49+
/// Adds a custom action to be executed for each entity of type <typeparamref name="TEntity"/> being saved or updated.
50+
/// </summary>
51+
/// <param name="action">The action to execute.</param>
52+
/// <returns><see cref="IDirectiveInterceptorConfigurationBuilder{TEntity}"/> to allow further configuration.</returns>
53+
public IDirectiveInterceptorConfigurationBuilder<TEntity> Invoke(Action<DbContext, TEntity> action);
54+
}

src/BitzArt.CA.Persistence.EntityFrameworkCore/Interceptors/PropertyForwarding/Configuration/IPropertyForwardingInterceptorConfigurationRuleBuilder.cs renamed to src/BitzArt.CA.Persistence.EntityFrameworkCore/Interceptors/PropertyForwarding/Configuration/IDirectiveInterceptorForwardingRuleBuilder.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ namespace BitzArt.CA.Persistence;
99
/// </summary>
1010
/// <typeparam name="TEntity">Entity type.</typeparam>
1111
/// <typeparam name="TProperty">Property type.</typeparam>
12-
public interface IPropertyForwardingInterceptorConfigurationRuleBuilder<TEntity, TProperty>
12+
public interface IDirectiveInterceptorForwardingRuleBuilder<TEntity, TProperty>
1313
where TEntity : class
1414
{
1515
/// <summary>
1616
/// Specifies the target property to which the value will be forwarded.
1717
/// </summary>
1818
/// <param name="propertyName">Name of the property to set the value to.</param>
19-
/// <returns><see cref="IPropertyForwardingInterceptorConfigurationBuilder{TEntity}"/> to allow further configuration.</returns>
20-
public IPropertyForwardingInterceptorConfigurationBuilder<TEntity> To(string propertyName)
19+
/// <returns><see cref="IDirectiveInterceptorConfigurationBuilder{TEntity}"/> to allow further configuration.</returns>
20+
public IDirectiveInterceptorConfigurationBuilder<TEntity> To(string propertyName)
2121
=> To((dbContext, entity, value) =>
2222
{
2323
var entry = dbContext.Entry(entity);
@@ -29,8 +29,8 @@ public IPropertyForwardingInterceptorConfigurationBuilder<TEntity> To(string pro
2929
/// Specifies the target property to which the value will be forwarded.
3030
/// </summary>
3131
/// <param name="targetPropertyExpression">Expression to specify the target property.</param>
32-
/// <returns><see cref="IPropertyForwardingInterceptorConfigurationBuilder{TEntity}"/> to allow further configuration.</returns>
33-
public IPropertyForwardingInterceptorConfigurationBuilder<TEntity> To(Expression<Func<TEntity, TProperty>> targetPropertyExpression)
32+
/// <returns><see cref="IDirectiveInterceptorConfigurationBuilder{TEntity}"/> to allow further configuration.</returns>
33+
public IDirectiveInterceptorConfigurationBuilder<TEntity> To(Expression<Func<TEntity, TProperty>> targetPropertyExpression)
3434
{
3535
var memberExpression = targetPropertyExpression.Body as MemberExpression
3636
?? throw new ArgumentException("The expression must be a member expression.", nameof(targetPropertyExpression));
@@ -48,13 +48,13 @@ public IPropertyForwardingInterceptorConfigurationBuilder<TEntity> To(Expression
4848
}
4949

5050
/// <inheritdoc cref="To(Action{DbContext, TEntity, TProperty})"/>
51-
public IPropertyForwardingInterceptorConfigurationBuilder<TEntity> To(Action<TEntity, TProperty> targetValueSetter)
51+
public IDirectiveInterceptorConfigurationBuilder<TEntity> To(Action<TEntity, TProperty> targetValueSetter)
5252
=> To((_, entity, value) => targetValueSetter(entity, value));
5353

5454
/// <summary>
5555
/// Specifies the target property to which the value will be forwarded.
5656
/// </summary>
5757
/// <param name="targetValueSetter">Action to set the value to the target property.</param>
58-
/// <returns><see cref="IPropertyForwardingInterceptorConfigurationBuilder{TEntity}"/> to allow further configuration.</returns>
59-
public IPropertyForwardingInterceptorConfigurationBuilder<TEntity> To(Action<DbContext, TEntity, TProperty> targetValueSetter);
58+
/// <returns><see cref="IDirectiveInterceptorConfigurationBuilder{TEntity}"/> to allow further configuration.</returns>
59+
public IDirectiveInterceptorConfigurationBuilder<TEntity> To(Action<DbContext, TEntity, TProperty> targetValueSetter);
6060
}

src/BitzArt.CA.Persistence.EntityFrameworkCore/Interceptors/PropertyForwarding/Configuration/IPropertyForwardingInterceptorConfigurationBuilder.cs

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/BitzArt.CA.Persistence.EntityFrameworkCore/Interceptors/PropertyForwarding/Configuration/PropertyForwardingInterceptorConfigurationBuilder.cs

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/BitzArt.CA.Persistence.EntityFrameworkCore/Interceptors/PropertyForwarding/Configuration/PropertyForwardingInterceptorConfigurationRuleBuilder.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace BitzArt.CA.Persistence;
4+
5+
/// <summary>
6+
/// An interceptor built using directives for handling entities of type <typeparamref name="TEntity"/>.
7+
/// </summary>
8+
public sealed class DirectiveInterceptor<TEntity> : OnSaveInterceptorBase
9+
where TEntity : class
10+
{
11+
private readonly List<Action<DbContext, TEntity>> _directives = [];
12+
13+
/// <summary>
14+
/// Creates a new instance of <see cref="DirectiveInterceptor{TEntity}"/>.
15+
/// </summary>
16+
/// <param name="configure"></param>
17+
public DirectiveInterceptor(Action<IDirectiveInterceptorConfigurationBuilder<TEntity>> configure)
18+
{
19+
var configurationBuilder = new DirectiveInterceptorConfigurationBuilder<TEntity>(this);
20+
configure.Invoke(configurationBuilder);
21+
}
22+
23+
/// <inheritdoc/>
24+
protected override void OnSave(DbContext dbContext)
25+
{
26+
var entities = dbContext.ChangeTracker
27+
.Entries<TEntity>()
28+
.Where(e => e.State > EntityState.Unchanged)
29+
.Select(e => e.Entity);
30+
31+
foreach (var entity in entities)
32+
{
33+
ApplyDirectives(dbContext, entity);
34+
}
35+
}
36+
37+
private void ApplyDirectives(DbContext dbContext, TEntity entity)
38+
{
39+
foreach (var rule in _directives)
40+
{
41+
rule.Invoke(dbContext, entity);
42+
}
43+
}
44+
45+
internal void AddDirective(Action<DbContext, TEntity> rule)
46+
{
47+
_directives.Add(rule);
48+
}
49+
}

src/BitzArt.CA.Persistence.EntityFrameworkCore/Interceptors/PropertyForwarding/PropertyForwardingInterceptor.cs

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/BitzArt.CA.Persistence.EntityFrameworkCore/Interceptors/PropertyForwarding/PropertyForwardingRule.cs

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)