-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce ResilienceProperties (#1062)
- Loading branch information
Showing
12 changed files
with
349 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
using System; | ||
using FluentAssertions; | ||
using Xunit; | ||
|
||
namespace Polly.Core.Tests; | ||
|
||
public class ResiliencePropertiesTests | ||
{ | ||
[Fact] | ||
public void TryGetValue_Ok() | ||
{ | ||
var key = new ResiliencePropertyKey<long>("dummy"); | ||
var props = new ResilienceProperties(); | ||
|
||
props.Set(key, 12345); | ||
|
||
props.TryGetValue(key, out var val).Should().Be(true); | ||
val.Should().Be(12345); | ||
} | ||
|
||
[Fact] | ||
public void TryGetValue_NotFound_Ok() | ||
{ | ||
var key = new ResiliencePropertyKey<long>("dummy"); | ||
var props = new ResilienceProperties(); | ||
|
||
props.TryGetValue(key, out var val).Should().Be(false); | ||
} | ||
|
||
[Fact] | ||
public void GetValue_Ok() | ||
{ | ||
var key = new ResiliencePropertyKey<long>("dummy"); | ||
var props = new ResilienceProperties(); | ||
|
||
props.Set(key, 12345); | ||
|
||
props.GetValue(key, default).Should().Be(12345); | ||
} | ||
|
||
[Fact] | ||
public void GetValue_NotFound_EnsureDefault() | ||
{ | ||
var key = new ResiliencePropertyKey<long>("dummy"); | ||
var props = new ResilienceProperties(); | ||
|
||
props.GetValue(key, -1).Should().Be(-1); | ||
} | ||
|
||
[Fact] | ||
public void TryGetValue_IncorrectType_NotFound() | ||
{ | ||
var key1 = new ResiliencePropertyKey<long>("dummy"); | ||
var key2 = new ResiliencePropertyKey<string>("dummy"); | ||
|
||
var props = new ResilienceProperties(); | ||
|
||
props.Set(key1, 12345); | ||
|
||
props.TryGetValue(key2, out var val).Should().Be(false); | ||
} | ||
|
||
[Fact] | ||
public void DictionaryOperations_Ok() | ||
{ | ||
IDictionary<string, object?> dict = new ResilienceProperties(); | ||
|
||
dict.TryGetValue("xyz", out var _).Should().BeFalse(); | ||
dict.GetEnumerator().Should().NotBeNull(); | ||
((IEnumerable)dict).GetEnumerator().Should().NotBeNull(); | ||
dict.IsReadOnly.Should().BeFalse(); | ||
dict.Count.Should().Be(0); | ||
dict.Add("dummy", 12345L); | ||
dict.Values.Should().Contain(12345L); | ||
dict.Keys.Should().Contain("dummy"); | ||
dict.ContainsKey("dummy").Should().BeTrue(); | ||
dict.Contains(new KeyValuePair<string, object?>("dummy", 12345L)).Should().BeTrue(); | ||
dict.Add("dummy2", "xyz"); | ||
dict["dummy2"].Should().Be("xyz"); | ||
dict["dummy3"] = "abc"; | ||
dict["dummy3"].Should().Be("abc"); | ||
dict.Remove("dummy2").Should().BeTrue(); | ||
dict.Remove(new KeyValuePair<string, object?>("not-exists", "abc")).Should().BeFalse(); | ||
dict.Clear(); | ||
dict.Count.Should().Be(0); | ||
dict.Add(new KeyValuePair<string, object?>("dummy", "abc")); | ||
var array = new KeyValuePair<string, object?>[1]; | ||
dict.CopyTo(array, 0); | ||
array[0].Key.Should().Be("dummy"); | ||
array[0].Value.Should().Be("abc"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
using System; | ||
using FluentAssertions; | ||
using Xunit; | ||
|
||
namespace Polly.Core.Tests; | ||
|
||
public class ResiliencePropertyKeyTests | ||
{ | ||
[Fact] | ||
public void Ctor_Ok() | ||
{ | ||
var instance = new ResiliencePropertyKey<int>("dummy"); | ||
|
||
instance.Key.Should().Be("dummy"); | ||
instance.ToString().Should().Be("dummy"); | ||
} | ||
|
||
[Fact] | ||
public void Ctor_Null_Throws() | ||
{ | ||
Assert.Throws<ArgumentNullException>(() => new ResiliencePropertyKey<int>(null!)); | ||
} | ||
|
||
[Fact] | ||
public void Equality_Ok() | ||
{ | ||
var key1 = new ResiliencePropertyKey<string>("dummy"); | ||
var key2 = new ResiliencePropertyKey<string>("dummy"); | ||
|
||
key1.Equals(key2).Should().BeTrue(); | ||
key1.Equals(new ResiliencePropertyKey<string>("dummy2")).Should().BeFalse(); | ||
key1.Equals(new ResiliencePropertyKey<object>("dummy")).Should().BeFalse(); | ||
|
||
key1.Equals((object)key2).Should().BeTrue(); | ||
key1.Equals((object)new ResiliencePropertyKey<string>("dummy2")).Should().BeFalse(); | ||
|
||
(key1 == key2).Should().BeTrue(); | ||
(key1 != key2).Should().BeFalse(); | ||
} | ||
|
||
[Fact] | ||
public void GetHashCode_Ok() | ||
{ | ||
var key1 = new ResiliencePropertyKey<string>("dummy"); | ||
var key2 = new ResiliencePropertyKey<string>("dummy"); | ||
|
||
key1.GetHashCode().Should().Be(key2.GetHashCode()); | ||
key1.GetHashCode().Should().NotBe(new ResiliencePropertyKey<string>("dummy2").GetHashCode()); | ||
key1.GetHashCode().Should().NotBe(new ResiliencePropertyKey<object>("dummy").GetHashCode()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#if NETFRAMEWORK || NETSTANDARD | ||
|
||
namespace System.Diagnostics.CodeAnalysis; | ||
|
||
[AttributeUsage(AttributeTargets.Parameter)] | ||
internal sealed class MaybeNullWhenAttribute : Attribute | ||
{ | ||
public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; | ||
|
||
public bool ReturnValue { get; } | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
using System.Diagnostics.CodeAnalysis; | ||
|
||
namespace Polly; | ||
|
||
#pragma warning disable CA1710 // Identifiers should have correct suffix | ||
|
||
/// <summary> | ||
/// Represents a collection of custom resilience properties. | ||
/// </summary> | ||
public sealed class ResilienceProperties : IDictionary<string, object?> | ||
{ | ||
private Dictionary<string, object?> Options { get; } = new(); | ||
|
||
/// <summary> | ||
/// Gets the value of a given property. | ||
/// </summary> | ||
/// <param name="key">Strongly typed key to get the value of the property.</param> | ||
/// <param name="value">Returns the value of the property.</param> | ||
/// <typeparam name="TValue">The type of property value as defined by <paramref name="key"/> parameter.</typeparam> | ||
/// <returns>True, if a property was retrieved.</returns> | ||
public bool TryGetValue<TValue>(ResiliencePropertyKey<TValue> key, [MaybeNullWhen(false)] out TValue value) | ||
{ | ||
if (Options.TryGetValue(key.Key, out object? val) && val is TValue typedValue) | ||
{ | ||
value = typedValue; | ||
return true; | ||
} | ||
|
||
value = default; | ||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the value of a given property with a fallback default value. | ||
/// </summary> | ||
/// <param name="key">Strongly typed key to get the value of the property.</param> | ||
/// <param name="defaultValue">The default value to use if property is not found.</param> | ||
/// <typeparam name="TValue">The type of property value as defined by <paramref name="key"/> parameter.</typeparam> | ||
/// <returns>The property value or the default value.</returns> | ||
public TValue GetValue<TValue>(ResiliencePropertyKey<TValue> key, TValue defaultValue) | ||
{ | ||
if (TryGetValue(key, out var value)) | ||
{ | ||
return value; | ||
} | ||
|
||
return defaultValue; | ||
} | ||
|
||
/// <summary> | ||
/// Sets the value of a given property. | ||
/// </summary> | ||
/// <param name="key">Strongly typed key to get the value of the property.</param> | ||
/// <param name="value">Returns the value of the property.</param> | ||
/// <typeparam name="TValue">The type of property value as defined by <paramref name="key"/> parameter.</typeparam> | ||
public void Set<TValue>(ResiliencePropertyKey<TValue> key, TValue value) | ||
{ | ||
Options[key.Key] = value; | ||
} | ||
|
||
/// <inheritdoc/> | ||
object? IDictionary<string, object?>.this[string key] | ||
{ | ||
get => Options[key]; | ||
set => Options[key] = value; | ||
} | ||
|
||
/// <inheritdoc/> | ||
ICollection<string> IDictionary<string, object?>.Keys => Options.Keys; | ||
|
||
/// <inheritdoc/> | ||
ICollection<object?> IDictionary<string, object?>.Values => Options.Values; | ||
|
||
/// <inheritdoc/> | ||
int ICollection<KeyValuePair<string, object?>>.Count => Options.Count; | ||
|
||
/// <inheritdoc/> | ||
bool ICollection<KeyValuePair<string, object?>>.IsReadOnly => ((IDictionary<string, object?>)Options).IsReadOnly; | ||
|
||
/// <inheritdoc/> | ||
void IDictionary<string, object?>.Add(string key, object? value) => Options.Add(key, value); | ||
|
||
/// <inheritdoc/> | ||
void ICollection<KeyValuePair<string, object?>>.Add(KeyValuePair<string, object?> item) => ((IDictionary<string, object?>)Options).Add(item); | ||
|
||
/// <inheritdoc/> | ||
void ICollection<KeyValuePair<string, object?>>.Clear() => Options.Clear(); | ||
|
||
/// <inheritdoc/> | ||
bool ICollection<KeyValuePair<string, object?>>.Contains(KeyValuePair<string, object?> item) => ((IDictionary<string, object?>)Options).Contains(item); | ||
|
||
/// <inheritdoc/> | ||
bool IDictionary<string, object?>.ContainsKey(string key) => Options.ContainsKey(key); | ||
|
||
/// <inheritdoc/> | ||
void ICollection<KeyValuePair<string, object?>>.CopyTo(KeyValuePair<string, object?>[] array, int arrayIndex) => | ||
((IDictionary<string, object?>)Options).CopyTo(array, arrayIndex); | ||
|
||
/// <inheritdoc/> | ||
IEnumerator<KeyValuePair<string, object?>> IEnumerable<KeyValuePair<string, object?>>.GetEnumerator() => Options.GetEnumerator(); | ||
|
||
/// <inheritdoc/> | ||
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)Options).GetEnumerator(); | ||
|
||
/// <inheritdoc/> | ||
bool IDictionary<string, object?>.Remove(string key) => Options.Remove(key); | ||
|
||
/// <inheritdoc/> | ||
bool ICollection<KeyValuePair<string, object?>>.Remove(KeyValuePair<string, object?> item) => ((IDictionary<string, object?>)Options).Remove(item); | ||
|
||
/// <inheritdoc/> | ||
bool IDictionary<string, object?>.TryGetValue(string key, out object? value) => Options.TryGetValue(key, out value); | ||
} | ||
|
Oops, something went wrong.