From 950775b65093e22ce209c947bf9da71b17ad7387 Mon Sep 17 00:00:00 2001 From: Austin Drenski Date: Wed, 17 Jan 2024 13:22:04 -0500 Subject: [PATCH 1/3] fix: Fix ArgumentOutOfRangeException for empty hooks (#187) Signed-off-by: Austin Drenski --- src/OpenFeature/Api.cs | 21 ++++++++++++++++++- src/OpenFeature/OpenFeatureClient.cs | 21 ++++++++++++++++++- .../OpenFeature.Tests/OpenFeatureHookTests.cs | 7 +++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/OpenFeature/Api.cs b/src/OpenFeature/Api.cs index 8d0e22f5..440242da 100644 --- a/src/OpenFeature/Api.cs +++ b/src/OpenFeature/Api.cs @@ -127,7 +127,26 @@ public FeatureClient GetClient(string name = null, string version = null, ILogge /// /// /// A list of - public void AddHooks(IEnumerable hooks) => this._hooks.PushRange(hooks.ToArray()); + public void AddHooks(IEnumerable hooks) +#if NET7_0_OR_GREATER + => this._hooks.PushRange(hooks as Hook[] ?? hooks.ToArray()); +#else + { + // See: https://github.com/dotnet/runtime/issues/62121 + if (hooks is Hook[] array) + { + if (array.Length > 0) + this._hooks.PushRange(array); + + return; + } + + array = hooks.ToArray(); + + if (array.Length > 0) + this._hooks.PushRange(array); + } +#endif /// /// Adds a hook to global hooks list diff --git a/src/OpenFeature/OpenFeatureClient.cs b/src/OpenFeature/OpenFeatureClient.cs index 9ea9b13a..d979dae1 100644 --- a/src/OpenFeature/OpenFeatureClient.cs +++ b/src/OpenFeature/OpenFeatureClient.cs @@ -106,7 +106,26 @@ public void RemoveHandler(ProviderEventTypes type, EventHandlerDelegate handler) } /// - public void AddHooks(IEnumerable hooks) => this._hooks.PushRange(hooks.ToArray()); + public void AddHooks(IEnumerable hooks) +#if NET7_0_OR_GREATER + => this._hooks.PushRange(hooks as Hook[] ?? hooks.ToArray()); +#else + { + // See: https://github.com/dotnet/runtime/issues/62121 + if (hooks is Hook[] array) + { + if (array.Length > 0) + this._hooks.PushRange(array); + + return; + } + + array = hooks.ToArray(); + + if (array.Length > 0) + this._hooks.PushRange(array); + } +#endif /// public IEnumerable GetHooks() => this._hooks.Reverse(); diff --git a/test/OpenFeature.Tests/OpenFeatureHookTests.cs b/test/OpenFeature.Tests/OpenFeatureHookTests.cs index a4810c04..b3aee4d8 100644 --- a/test/OpenFeature.Tests/OpenFeatureHookTests.cs +++ b/test/OpenFeature.Tests/OpenFeatureHookTests.cs @@ -553,5 +553,12 @@ public async Task When_Error_Occurs_In_After_Hook_Should_Invoke_Error_Hook() await featureProvider.DidNotReceive().ResolveBooleanValue("test", false, Arg.Any()); } + + [Fact] + public void Add_hooks_should_accept_empty_enumerable() + { + Api.Instance.ClearHooks(); + Api.Instance.AddHooks(Enumerable.Empty()); + } } } From 1efe09da3948d5dfd7fd9f1c7a040fc5c2cbe833 Mon Sep 17 00:00:00 2001 From: Michael Beemer Date: Wed, 17 Jan 2024 17:42:15 -0500 Subject: [PATCH 2/3] chore: remove duplicate eventing section in readme Signed-off-by: Michael Beemer --- README.md | 54 +++++++++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index f504211c..33cf5c5d 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,31 @@ client.AddHooks(new ExampleClientHook()); var value = await client.GetBooleanValue("boolFlag", false, context, new FlagEvaluationOptions(new ExampleInvocationHook())); ``` +### Logging + +The .NET SDK uses Microsoft.Extensions.Logging. See the [manual](https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line) for complete documentation. + +### Named clients + +Clients can be given a name. +A name is a logical identifier that can be used to associate clients with a particular provider. +If a name has no associated provider, the global provider is used. + +```csharp +// registering the default provider +await Api.Instance.SetProvider(new LocalProvider()); + +// registering a named provider +await Api.Instance.SetProvider("clientForCache", new CachedProvider()); + +// a client backed by default provider +FeatureClient clientDefault = Api.Instance.GetClient(); + +// a client backed by CachedProvider +FeatureClient clientNamed = Api.Instance.GetClient("clientForCache"); + +``` + ### Eventing Events allow you to react to state changes in the provider or underlying flag management system, such as flag definition changes, @@ -204,35 +229,6 @@ await Api.Instance.SetProvider(myClient.GetMetadata().Name, provider); myClient.AddHandler(ProviderEventTypes.ProviderReady, callback); ``` -### Logging - -The .NET SDK uses Microsoft.Extensions.Logging. See the [manual](https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line) for complete documentation. - -### Named clients - -Clients can be given a name. -A name is a logical identifier that can be used to associate clients with a particular provider. -If a name has no associated provider, the global provider is used. - -```csharp -// registering the default provider -await Api.Instance.SetProvider(new LocalProvider()); - -// registering a named provider -await Api.Instance.SetProvider("clientForCache", new CachedProvider()); - -// a client backed by default provider -FeatureClient clientDefault = Api.Instance.GetClient(); - -// a client backed by CachedProvider -FeatureClient clientNamed = Api.Instance.GetClient("clientForCache"); - -``` - -### Eventing - -Events are currently not supported by the .NET SDK. Progress on this feature can be tracked [here](https://github.com/open-feature/dotnet-sdk/issues/126). - ### Shutdown The OpenFeature API provides a close function to perform a cleanup of all registered providers. This should only be called when your application is in the process of shutting down. From 18a092afcab1b06c25f3b825a6130d22226790fc Mon Sep 17 00:00:00 2001 From: Austin Drenski Date: Thu, 18 Jan 2024 14:56:53 -0500 Subject: [PATCH 3/3] chore: Fix FieldCanBeMadeReadOnly (#183) Signed-off-by: Austin Drenski --- src/OpenFeature/FeatureProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenFeature/FeatureProvider.cs b/src/OpenFeature/FeatureProvider.cs index 3dd85102..000ab0fb 100644 --- a/src/OpenFeature/FeatureProvider.cs +++ b/src/OpenFeature/FeatureProvider.cs @@ -29,7 +29,7 @@ public abstract class FeatureProvider /// /// The event channel of the provider. /// - protected Channel EventChannel = Channel.CreateBounded(1); + protected readonly Channel EventChannel = Channel.CreateBounded(1); /// /// Metadata describing the provider.