Skip to content

Commit ed35ad2

Browse files
committed
Possible method-chaining fluent syntax for monkey policy options
1 parent cd409fb commit ed35ad2

13 files changed

+290
-179
lines changed

src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourAsyncWithOptionsSpecs.cs

+38-41
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Polly.Contrib.Simmy.Utilities;
33
using System;
44
using System.Threading.Tasks;
5+
using Polly.Contrib.Simmy.Behavior.Options;
56
using Xunit;
67

78
namespace Polly.Contrib.Simmy.Specs.Behavior
@@ -25,16 +26,15 @@ public void Given_not_enabled_should_not_inject_behaviour()
2526
Boolean userDelegateExecuted = false;
2627
Boolean injectedBehaviourExecuted = false;
2728

28-
var policy = MonkeyPolicy.InjectBehaviourAsync(options =>
29-
{
30-
options.InjectionRate = 0.6;
31-
options.Enabled = () => false;
32-
options.Behaviour = () =>
33-
{
34-
injectedBehaviourExecuted = true;
35-
return Task.CompletedTask;
36-
};
37-
});
29+
var policy = MonkeyPolicy.InjectBehaviourAsync(with =>
30+
with.Behaviour(() =>
31+
{
32+
injectedBehaviourExecuted = true;
33+
return Task.CompletedTask;
34+
})
35+
.InjectionRate(0.6)
36+
.Enabled(false)
37+
);
3838

3939
policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });
4040

@@ -48,16 +48,15 @@ public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour(
4848
Boolean userDelegateExecuted = false;
4949
Boolean injectedBehaviourExecuted = false;
5050

51-
var policy = MonkeyPolicy.InjectBehaviourAsync(options =>
52-
{
53-
options.InjectionRate = 0.6;
54-
options.Enabled = () => true;
55-
options.Behaviour = () =>
56-
{
57-
injectedBehaviourExecuted = true;
58-
return Task.CompletedTask;
59-
};
60-
});
51+
var policy = MonkeyPolicy.InjectBehaviourAsync(with =>
52+
with.Behaviour(() =>
53+
{
54+
injectedBehaviourExecuted = true;
55+
return Task.CompletedTask;
56+
})
57+
.InjectionRate(0.6)
58+
.Enabled()
59+
);
6160

6261
policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });
6362

@@ -71,16 +70,15 @@ public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_be
7170
Boolean userDelegateExecuted = false;
7271
Boolean injectedBehaviourExecuted = false;
7372

74-
var policy = MonkeyPolicy.InjectBehaviourAsync(options =>
75-
{
76-
options.InjectionRate = 0.4;
77-
options.Enabled = () => true;
78-
options.Behaviour = () =>
79-
{
80-
injectedBehaviourExecuted = true;
81-
return Task.CompletedTask;
82-
};
83-
});
73+
var policy = MonkeyPolicy.InjectBehaviourAsync(with =>
74+
with.Behaviour(() =>
75+
{
76+
injectedBehaviourExecuted = true;
77+
return Task.CompletedTask;
78+
})
79+
.InjectionRate(0.4)
80+
.Enabled(false)
81+
);
8482

8583
policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });
8684

@@ -94,17 +92,16 @@ public void Should_inject_behaviour_before_executing_user_delegate()
9492
Boolean userDelegateExecuted = false;
9593
Boolean injectedBehaviourExecuted = false;
9694

97-
var policy = MonkeyPolicy.InjectBehaviourAsync(options =>
98-
{
99-
options.InjectionRate = 0.6;
100-
options.Enabled = () => true;
101-
options.Behaviour = () =>
102-
{
103-
userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.
104-
injectedBehaviourExecuted = true;
105-
return Task.CompletedTask;
106-
};
107-
});
95+
var policy = MonkeyPolicy.InjectBehaviourAsync(with =>
96+
with.Behaviour(() =>
97+
{
98+
userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.
99+
injectedBehaviourExecuted = true;
100+
return Task.CompletedTask;
101+
})
102+
.InjectionRate(0.6)
103+
.Enabled()
104+
);
108105

109106
policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });
110107

src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourWithOptionsSpecs.cs

+21-28
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using FluentAssertions;
3+
using Polly.Contrib.Simmy.Behavior.Options;
34
using Polly.Contrib.Simmy.Utilities;
45
using Xunit;
56

@@ -24,12 +25,10 @@ public void Given_not_enabled_should_not_inject_behaviour()
2425
Boolean userDelegateExecuted = false;
2526
Boolean injectedBehaviourExecuted = false;
2627

27-
var policy = MonkeyPolicy.InjectBehaviour(options =>
28-
{
29-
options.InjectionRate = 0.6;
30-
options.Enabled = () => false;
31-
options.Behaviour = () => { injectedBehaviourExecuted = true; };
32-
});
28+
var policy = MonkeyPolicy.InjectBehaviour(with =>
29+
with.Behaviour(() => { injectedBehaviourExecuted = true; })
30+
.InjectionRate(0.6)
31+
.Enabled(false));
3332

3433
policy.Execute(() => { userDelegateExecuted = true; });
3534

@@ -43,12 +42,10 @@ public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour(
4342
Boolean userDelegateExecuted = false;
4443
Boolean injectedBehaviourExecuted = false;
4544

46-
var policy = MonkeyPolicy.InjectBehaviour(options =>
47-
{
48-
options.InjectionRate = 0.6;
49-
options.Enabled = () => true;
50-
options.Behaviour = () => { injectedBehaviourExecuted = true; };
51-
});
45+
var policy = MonkeyPolicy.InjectBehaviour(with =>
46+
with.Behaviour(() => { injectedBehaviourExecuted = true; })
47+
.InjectionRate(0.6)
48+
.Enabled());
5249

5350
policy.Execute(() => { userDelegateExecuted = true; });
5451

@@ -62,12 +59,10 @@ public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_be
6259
Boolean userDelegateExecuted = false;
6360
Boolean injectedBehaviourExecuted = false;
6461

65-
var policy = MonkeyPolicy.InjectBehaviour(options =>
66-
{
67-
options.InjectionRate = 0.4;
68-
options.Enabled = () => true;
69-
options.Behaviour = () => { injectedBehaviourExecuted = true; };
70-
});
62+
var policy = MonkeyPolicy.InjectBehaviour(with =>
63+
with.Behaviour(() => { injectedBehaviourExecuted = true; })
64+
.InjectionRate(0.4)
65+
.Enabled());
7166

7267
policy.Execute(() => { userDelegateExecuted = true; });
7368

@@ -81,16 +76,14 @@ public void Should_inject_behaviour_before_executing_user_delegate()
8176
Boolean userDelegateExecuted = false;
8277
Boolean injectedBehaviourExecuted = false;
8378

84-
var policy = MonkeyPolicy.InjectBehaviour(options =>
85-
{
86-
options.InjectionRate = 0.6;
87-
options.Enabled = () => true;
88-
options.Behaviour = () =>
89-
{
90-
userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.
91-
injectedBehaviourExecuted = true;
92-
};
93-
});
79+
var policy = MonkeyPolicy.InjectBehaviour(with =>
80+
with.Behaviour(() =>
81+
{
82+
userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.
83+
injectedBehaviourExecuted = true;
84+
})
85+
.InjectionRate(0.6)
86+
.Enabled());
9487

9588
policy.Execute(() => { userDelegateExecuted = true; });
9689

src/Polly.Contrib.Simmy/Behavior/AsyncInjectBehaviourOptionsSyntax.cs

-24
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,5 @@ public static AsyncInjectBehaviourPolicy InjectBehaviourAsync(Action<InjectBehav
3131
options.InjectionRate,
3232
options.Enabled);
3333
}
34-
35-
/// <summary>
36-
/// Builds a <see cref="AsyncInjectBehaviourPolicy"/> which executes a behaviour if <paramref name="configureOptions.Enabled"/> returns true and
37-
/// a random number is within range of <paramref name="configureOptions.InjectionRate"/>.
38-
/// </summary>
39-
/// <param name="configureOptions">A callback to configure policy options.</param>
40-
/// <returns>The policy instance.</returns>
41-
public static AsyncInjectBehaviourPolicy InjectBehaviourAsync(Action<InjectBehaviourAsyncBasicOptions> configureOptions)
42-
{
43-
var options = new InjectBehaviourAsyncBasicOptions();
44-
configureOptions.Invoke(options);
45-
46-
if (options.Behaviour == null) throw new ArgumentNullException(nameof(options.Behaviour));
47-
if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));
48-
49-
Task BehaviourLambda(Context _, CancellationToken __) => options.Behaviour();
50-
Task<Double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(options.InjectionRate);
51-
Task<bool> EnabledLambda(Context _, CancellationToken __) => Task.FromResult(options.Enabled());
52-
53-
return new AsyncInjectBehaviourPolicy(
54-
BehaviourLambda,
55-
InjectionRateLambda,
56-
EnabledLambda);
57-
}
5834
}
5935
}

src/Polly.Contrib.Simmy/Behavior/InjectBehaviourOptionsSyntax.cs

-24
Original file line numberDiff line numberDiff line change
@@ -30,29 +30,5 @@ public static InjectBehaviourPolicy InjectBehaviour(Action<InjectBehaviourOption
3030
options.InjectionRate,
3131
options.Enabled);
3232
}
33-
34-
/// <summary>
35-
/// Builds a <see cref="InjectBehaviourPolicy"/> which executes a behaviour if <paramref name="configureOptions.Enabled"/> returns true and
36-
/// a random number is within range of <paramref name="configureOptions.InjectionRate"/>.
37-
/// </summary>
38-
/// <param name="configureOptions">A callback to configure policy options.</param>
39-
/// <returns>The policy instance.</returns>
40-
public static InjectBehaviourPolicy InjectBehaviour(Action<InjectBehaviourBasicOptions> configureOptions)
41-
{
42-
var options = new InjectBehaviourBasicOptions();
43-
configureOptions.Invoke(options);
44-
45-
if (options.Behaviour == null) throw new ArgumentNullException(nameof(options.Behaviour));
46-
if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));
47-
48-
void BehaviourLambda(Context _, CancellationToken __) => options.Behaviour();
49-
double InjectionRateLambda(Context _, CancellationToken __) => options.InjectionRate;
50-
bool EnabledLambda(Context _, CancellationToken __) => options.Enabled();
51-
52-
return new InjectBehaviourPolicy(
53-
BehaviourLambda,
54-
InjectionRateLambda,
55-
EnabledLambda);
56-
}
5733
}
5834
}

src/Polly.Contrib.Simmy/Behavior/Options/InjectBehaviourAsyncOptions.cs

+2-21
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,11 @@ namespace Polly.Contrib.Simmy.Behavior.Options
77
/// <summary>
88
/// Options used to configure an <see cref="AsyncInjectBehaviourPolicy"/>
99
/// </summary>
10-
public class InjectBehaviourAsyncOptions
10+
public class InjectBehaviourAsyncOptions : InjectOptionsAsyncBase
1111
{
1212
/// <summary>
1313
/// Behaviour Delegate to be executed
1414
/// </summary>
15-
public Func<Context, CancellationToken, Task> Behaviour { get; set; }
16-
17-
/// <summary>
18-
/// Lambda to get injection rate between [0, 1]
19-
/// </summary>
20-
public Func<Context, CancellationToken, Task<Double>> InjectionRate { get; set; }
21-
22-
/// <summary>
23-
/// Lambda to check if this policy is enabled in current context
24-
/// </summary>
25-
public Func<Context, CancellationToken, Task<bool>> Enabled { get; set; }
26-
}
27-
28-
/// <inheritdoc/>
29-
public class InjectBehaviourAsyncBasicOptions : DefaultOptions
30-
{
31-
/// <summary>
32-
/// Behaviour Delegate to be executed without context
33-
/// </summary>
34-
public Func<Task> Behaviour { get; set; }
15+
internal Func<Context, CancellationToken, Task> Behaviour { get; set; }
3516
}
3617
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace Polly.Contrib.Simmy.Behavior.Options
6+
{
7+
/// <summary>
8+
/// Allows configuration of behaviour for asynchronous monkey behaviour-injection policies.
9+
/// </summary>
10+
public static class InjectBehaviourAsyncOptionsExtensions
11+
{
12+
/// <summary>
13+
/// Configure behaviour to inject with the monkey policy.
14+
/// </summary>
15+
/// <param name="options">The configuration object.</param>
16+
/// <param name="behaviour">A delegate representing the behaviour to inject.</param>
17+
public static InjectBehaviourAsyncOptions Behaviour(this InjectBehaviourAsyncOptions options, Func<Task> behaviour) =>
18+
Behaviour(options, (_, __) => behaviour());
19+
20+
/// <summary>
21+
/// Configure behaviour to inject with the monkey policy.
22+
/// </summary>
23+
/// <param name="options">The configuration object.</param>
24+
/// <param name="behaviour">A delegate representing the behaviour to inject.</param>
25+
public static InjectBehaviourAsyncOptions Behaviour(this InjectBehaviourAsyncOptions options, Func<Context, CancellationToken, Task> behaviour)
26+
{
27+
options.Behaviour = behaviour;
28+
return options;
29+
}
30+
}
31+
}

src/Polly.Contrib.Simmy/Behavior/Options/InjectBehaviourOptions.cs

+2-21
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,11 @@ namespace Polly.Contrib.Simmy.Behavior.Options
66
/// <summary>
77
/// Options used to configure an <see cref="AsyncInjectBehaviourPolicy"/>
88
/// </summary>
9-
public class InjectBehaviourOptions
9+
public class InjectBehaviourOptions : InjectOptionsBase
1010
{
1111
/// <summary>
1212
/// Behaviour Delegate to be executed
1313
/// </summary>
14-
public Action<Context, CancellationToken> Behaviour { get; set; }
15-
16-
/// <summary>
17-
/// Lambda to get injection rate between [0, 1]
18-
/// </summary>
19-
public Func<Context, CancellationToken, Double> InjectionRate{ get; set; }
20-
21-
/// <summary>
22-
/// Lambda to check if this policy is enabled in current context
23-
/// </summary>
24-
public Func<Context, CancellationToken, bool> Enabled{ get; set; }
25-
}
26-
27-
/// <inheritdoc/>
28-
public class InjectBehaviourBasicOptions : DefaultOptions
29-
{
30-
/// <summary>
31-
/// Behaviour Delegate to be executed without context
32-
/// </summary>
33-
public Action Behaviour { get; set; }
14+
internal Action<Context, CancellationToken> Behaviour { get; set; }
3415
}
3516
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.Threading;
3+
4+
namespace Polly.Contrib.Simmy.Behavior.Options
5+
{
6+
/// <summary>
7+
/// Allows configuration of behaviour for synchronous monkey behaviour-injection policies.
8+
/// </summary>
9+
public static class InjectBehaviourOptionsExtensions
10+
{
11+
/// <summary>
12+
/// Configure behaviour to inject with the monkey policy.
13+
/// </summary>
14+
/// <param name="options">The configuration object.</param>
15+
/// <param name="behaviour">A delegate representing the behaviour to inject.</param>
16+
public static InjectBehaviourOptions Behaviour(this InjectBehaviourOptions options, Action behaviour) =>
17+
Behaviour(options, (_, __) => behaviour());
18+
19+
/// <summary>
20+
/// Configure behaviour to inject with the monkey policy.
21+
/// </summary>
22+
/// <param name="options">The configuration object.</param>
23+
/// <param name="behaviour">A delegate representing the behaviour to inject.</param>
24+
public static InjectBehaviourOptions Behaviour(this InjectBehaviourOptions options, Action<Context, CancellationToken> behaviour)
25+
{
26+
options.Behaviour = behaviour;
27+
return options;
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)