I have a weak spot for the policy design pattern since ol' good C++ times: I think it has all started when I've read one of Sutter's / Alexandrescu's books with some great examples of policies injected via template parameters. This way you could get a variable behavior without complex inheritance and excessive coupling. Today, the times of templates are long gone (trust me: C# generics are 5% of what was possible with C++ templates ...), but it doesn't mean you can't use strategy / policy design patterns anymore.
Back to business:
The star of the day is named "Polly".
Polly is an exception handling policy library for .NET (3.5+; 4.0+) with a sweet (due to a proper dose of syntactic sugar), fluent syntax. What does it really mean?
-
You declaratively describe the behavior related to particular exception "class" handling. By class I mean subset of exceptions that meet some of the following criteria (1 or more):
- of a given type
- with an exception property that meets a given condition
-
Behavior may mean:
- retrying (indefinitely or set number of tries)
- retrying with a delay (may vary for each try)
- retrying with a context (do adjust the subsequent tries)
- break circuit (http://martinfowler.com/bliki/CircuitBreaker.html)
-
Such a policy may be applied to one or more lambdas of your choice. In case of applying a retry, you're the one to ensure that a re-execution of lambda make sense.
What's the benefit?
Basically: a very clean & maintainable code. Especially if you intend to re-use a particulr policy (same behavior) in many situations - you're abstracting (encapsulating & isolatings) your error-handling policies in a way that doesn't interfere with the actual business logic. Neat.
What is more, you're hiding the painful context (retrying, circuit breaking for a given time) - now it's hidden within a poliy, handled automatically & adjusting the behavior is as easy as it could only be.
If you want to have a look at the actual samples of code, just follow the link I gave above: https://github.com/michael-wolfenden/Polly. The code samples on the official GitHub page are much more than sufficient to present the capabilities of the library. Here's a sample, just to prove that the well-thought, fluent syntax doesn't need additional comments:
// first, create a policy that handles 2 types of exceptions &
// retries (whatever's to be retried) few times
var policy = Policy.Handle<SampleEx>(ex => true == ex.NeedsToBeHandled)
.Or<OtherEx>()
.WaitAndRetry(new[] {
1.Seconds(),
2.Seconds(),
5.Seconds(),
10.Seconds()
}, (ex, timeSpan, ctx) => {
// do something after each retry, like logging
});
// now, execute the policy with your action & some neat context
policy.Execute(
() => DoYourAction(),
new Dictionary<string, object>() {
{ "ctxKeySample", "ctxValueSample" }
});