From 42897af90e0c0f1e4d7be187f7637a3b455c146d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 12:45:07 +0000 Subject: [PATCH] chore(main): release 2.0.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 31 ++ README.md | 614 +++++++++++++++++----------------- build/Common.prod.props | 2 +- version.txt | 2 +- 5 files changed, 341 insertions(+), 310 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 0e5b256d..65f558e7 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.3.1" + ".": "2.0.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eae4599..72e7a172 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # Changelog +## [2.0.0](https://github.com/open-feature/dotnet-sdk/compare/v1.3.1...v2.0.0) (2023-12-28) + + +### โš  BREAKING CHANGES + +* Add support for provider shutdown and status. ([#158](https://github.com/open-feature/dotnet-sdk/issues/158)) + +### โœจ New Features + +* Add dx to catch ConfigureAwait(false) ([#152](https://github.com/open-feature/dotnet-sdk/issues/152)) ([9c42d4a](https://github.com/open-feature/dotnet-sdk/commit/9c42d4afa9139094e0316bbe1306ae4856b7d013)) +* Add support for provider shutdown and status. ([#158](https://github.com/open-feature/dotnet-sdk/issues/158)) ([24c3441](https://github.com/open-feature/dotnet-sdk/commit/24c344163423973b54a06b73648ba45b944589ee)) + + +### ๐Ÿงน Chore + +* add placeholder eventing and shutdown sections ([#156](https://github.com/open-feature/dotnet-sdk/issues/156)) ([5dfea29](https://github.com/open-feature/dotnet-sdk/commit/5dfea29bb3d01f6c8640de321c4fde52f283a1c0)) +* **deps:** update actions/checkout action to v4 ([#144](https://github.com/open-feature/dotnet-sdk/issues/144)) ([90d9d02](https://github.com/open-feature/dotnet-sdk/commit/90d9d021b227fba626bb99454cb7c0f7fef2d8d8)) +* **deps:** update actions/setup-dotnet action to v4 ([#162](https://github.com/open-feature/dotnet-sdk/issues/162)) ([0b0bb10](https://github.com/open-feature/dotnet-sdk/commit/0b0bb10419f836d9cc276fe8ac3c71c9214420ef)) +* **deps:** update github/codeql-action action to v3 ([#163](https://github.com/open-feature/dotnet-sdk/issues/163)) ([c85e93e](https://github.com/open-feature/dotnet-sdk/commit/c85e93e9c9a97083660f9062c38dcbf6d64a3ad6)) +* fix alt text for NuGet on the readme ([2cbdba8](https://github.com/open-feature/dotnet-sdk/commit/2cbdba80d836f8b7850e8dc5f1f1790ef2ed1aca)) +* update spec release link ([a2f70eb](https://github.com/open-feature/dotnet-sdk/commit/a2f70ebd68357156f9045fc6e94845a53ffd204a)) +* updated readme for inclusion in the docs ([6516866](https://github.com/open-feature/dotnet-sdk/commit/6516866ec7601a7adaa4dc6b517c9287dec54fca)) + + +### ๐Ÿ“š Documentation + +* Add README.md to the nuget package ([#164](https://github.com/open-feature/dotnet-sdk/issues/164)) ([b6b0ee2](https://github.com/open-feature/dotnet-sdk/commit/b6b0ee2b61a9b0b973b913b53887badfa0c5a3de)) +* fixed the contrib url on the readme ([9d8939e](https://github.com/open-feature/dotnet-sdk/commit/9d8939ef57a3be4ee220bd21f36b166887b2c30b)) +* remove duplicate a tag from readme ([2687cf0](https://github.com/open-feature/dotnet-sdk/commit/2687cf0663e20aa2dd113569cbf177833639cbbd)) +* update README.md ([#155](https://github.com/open-feature/dotnet-sdk/issues/155)) ([b62e21f](https://github.com/open-feature/dotnet-sdk/commit/b62e21f76964e7f6f7456f720814de0997232d71)) + ## [1.3.1](https://github.com/open-feature/dotnet-sdk/compare/v1.3.0...v1.3.1) (2023-09-19) diff --git a/README.md b/README.md index b625137b..585ee1bb 100644 --- a/README.md +++ b/README.md @@ -1,307 +1,307 @@ - - -

- - - OpenFeature Logo - -

- -

OpenFeature .NET SDK

- - - -

- - Specification - - - - - Release - - -
- - Slack - - - Codecov - - - NuGet - - - CII Best Practices - - -

- - -[OpenFeature](https://openfeature.dev) is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool. - - - -## ๐Ÿš€ Quick start - -### Requirements - -- .NET 6+ -- .NET Core 6+ -- .NET Framework 4.6.2+ - -Note that the packages will aim to support all current .NET versions. Refer to the currently supported versions [.NET](https://dotnet.microsoft.com/download/dotnet) and [.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework) excluding .NET Framework 3.5 - -### Install - -Use the following to initialize your project: - -```sh -dotnet new console -``` - -and install OpenFeature: - -```sh -dotnet add package OpenFeature -``` - -### Usage - -```csharp -public async Task Example() - { - // Register your feature flag provider - await Api.Instance.SetProvider(new InMemoryProvider()); - - // Create a new client - FeatureClient client = Api.Instance.GetClient(); - - // Evaluate your feature flag - bool v2Enabled = await client.GetBooleanValue("v2_enabled", false); - - if ( v2Enabled ) - { - //Do some work - } - } -``` - -## ๐ŸŒŸ Features - -| Status | Features | Description | -| ------ | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| โœ… | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. | -| โœ… | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). | -| โœ… | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. | -| โœ… | [Logging](#logging) | Integrate with popular logging packages. | -| โœ… | [Named clients](#named-clients) | Utilize multiple providers in a single application. | -| โŒ | [Eventing](#eventing) | React to state changes in the provider or flag management system. | -| โœ… | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. | -| โœ… | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. | - -Implemented: โœ… | In-progress: โš ๏ธ | Not implemented yet: โŒ - -### Providers - -[Providers](https://openfeature.dev/docs/reference/concepts/provider) are an abstraction between a flag management system and the OpenFeature SDK. -Here is [a complete list of available providers](https://openfeature.dev/ecosystem?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Provider&instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=.NET). - -If the provider you're looking for hasn't been created yet, see the [develop a provider](#develop-a-provider) section to learn how to build it yourself. - -Once you've added a provider as a dependency, it can be registered with OpenFeature like this: - -```csharp -await Api.Instance.SetProvider(new MyProvider()); -``` - -In some situations, it may be beneficial to register multiple providers in the same application. -This is possible using [named clients](#named-clients), which is covered in more detail below. - -### Targeting - -Sometimes, the value of a flag must consider some dynamic criteria about the application or user such as the user's location, IP, email address, or the server's location. -In OpenFeature, we refer to this as [targeting](https://openfeature.dev/specification/glossary#targeting). -If the flag management system you're using supports targeting, you can provide the input data using the [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). - -```csharp -// set a value to the global context -EvaluationContextBuilder builder = EvaluationContext.Builder(); -builder.Set("region", "us-east-1"); -EvaluationContext apiCtx = builder.Build(); -Api.Instance.SetContext(apiCtx); - -// set a value to the client context -builder = EvaluationContext.Builder(); -builder.Set("region", "us-east-1"); -EvaluationContext clientCtx = builder.Build(); -var client = Api.Instance.GetClient(); -client.SetContext(clientCtx); - -// set a value to the invocation context -builder = EvaluationContext.Builder(); -builder.Set("region", "us-east-1"); -EvaluationContext reqCtx = builder.Build(); - -bool flagValue = await client.GetBooleanValue("some-flag", false, reqCtx); - -``` - -### Hooks - -[Hooks](https://openfeature.dev/docs/reference/concepts/hooks) allow for custom logic to be added at well-defined points of the flag evaluation life-cycle. -Here is [a complete list of available hooks](https://openfeature.dev/docs/reference/technologies/server/dotnet/). -If the hook you're looking for hasn't been created yet, see the [develop a hook](#develop-a-hook) section to learn how to build it yourself. - -Once you've added a hook as a dependency, it can be registered at the global, client, or flag invocation level. - -```csharp -// add a hook globally, to run on all evaluations -Api.Instance.AddHooks(new ExampleGlobalHook()); - -// add a hook on this client, to run on all evaluations made by this client -var client = Api.Instance.GetClient(); -client.AddHooks(new ExampleClientHook()); - -// add a hook for this evaluation only -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 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. - -```csharp -// Shut down all providers -await Api.Instance.Shutdown(); -``` - -## Extending - -### Develop a provider - -To develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency. -This can be a new repository or included in [the existing contrib repository](https://github.com/open-feature/dotnet-sdk-contrib) available under the OpenFeature organization. -Youโ€™ll then need to write the provider by implementing the `FeatureProvider` interface exported by the OpenFeature SDK. - -```csharp -public class MyProvider : FeatureProvider - { - public override Metadata GetMetadata() - { - return new Metadata("My Provider"); - } - - public override Task> ResolveBooleanValue(string flagKey, bool defaultValue, EvaluationContext context = null) - { - // resolve a boolean flag value - } - - public override Task> ResolveDoubleValue(string flagKey, double defaultValue, EvaluationContext context = null) - { - // resolve a double flag value - } - - public override Task> ResolveIntegerValue(string flagKey, int defaultValue, EvaluationContext context = null) - { - // resolve an int flag value - } - - public override Task> ResolveStringValue(string flagKey, string defaultValue, EvaluationContext context = null) - { - // resolve a string flag value - } - - public override Task> ResolveStructureValue(string flagKey, Value defaultValue, EvaluationContext context = null) - { - // resolve an object flag value - } - } -``` - -### Develop a hook - -To develop a hook, you need to create a new project and include the OpenFeature SDK as a dependency. -This can be a new repository or included in [the existing contrib repository](https://github.com/open-feature/dotnet-sdk-contrib) available under the OpenFeature organization. -Implement your own hook by conforming to the `Hook interface`. -To satisfy the interface, all methods (`Before`/`After`/`Finally`/`Error`) need to be defined. - -```csharp -public class MyHook : Hook -{ - public Task Before(HookContext context, - IReadOnlyDictionary hints = null) - { - // code to run before flag evaluation - } - - public virtual Task After(HookContext context, FlagEvaluationDetails details, - IReadOnlyDictionary hints = null) - { - // code to run after successful flag evaluation - } - - public virtual Task Error(HookContext context, Exception error, - IReadOnlyDictionary hints = null) - { - // code to run if there's an error during before hooks or during flag evaluation - } - - public virtual Task Finally(HookContext context, IReadOnlyDictionary hints = null) - { - // code to run after all other stages, regardless of success/failure - } -} -``` - -Built a new hook? [Let us know](https://github.com/open-feature/openfeature.dev/issues/new?assignees=&labels=hook&projects=&template=document-hook.yaml&title=%5BHook%5D%3A+) so we can add it to the docs! - - -## โญ๏ธ Support the project - -- Give this repo a โญ๏ธ! -- Follow us on social media: - - Twitter: [@openfeature](https://twitter.com/openfeature) - - LinkedIn: [OpenFeature](https://www.linkedin.com/company/openfeature/) -- Join us on [Slack](https://cloud-native.slack.com/archives/C0344AANLA1) -- For more information, check out our [community page](https://openfeature.dev/community/) - -## ๐Ÿค Contributing - -Interested in contributing? Great, we'd love your help! To get started, take a look at the [CONTRIBUTING](CONTRIBUTING.md) guide. - -### Thanks to everyone who has already contributed - - - - - -Made with [contrib.rocks](https://contrib.rocks). - + + +

+ + + OpenFeature Logo + +

+ +

OpenFeature .NET SDK

+ + + +

+ + Specification + + + + + Release + + +
+ + Slack + + + Codecov + + + NuGet + + + CII Best Practices + + +

+ + +[OpenFeature](https://openfeature.dev) is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool. + + + +## ๐Ÿš€ Quick start + +### Requirements + +- .NET 6+ +- .NET Core 6+ +- .NET Framework 4.6.2+ + +Note that the packages will aim to support all current .NET versions. Refer to the currently supported versions [.NET](https://dotnet.microsoft.com/download/dotnet) and [.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework) excluding .NET Framework 3.5 + +### Install + +Use the following to initialize your project: + +```sh +dotnet new console +``` + +and install OpenFeature: + +```sh +dotnet add package OpenFeature +``` + +### Usage + +```csharp +public async Task Example() + { + // Register your feature flag provider + await Api.Instance.SetProvider(new InMemoryProvider()); + + // Create a new client + FeatureClient client = Api.Instance.GetClient(); + + // Evaluate your feature flag + bool v2Enabled = await client.GetBooleanValue("v2_enabled", false); + + if ( v2Enabled ) + { + //Do some work + } + } +``` + +## ๐ŸŒŸ Features + +| Status | Features | Description | +| ------ | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| โœ… | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. | +| โœ… | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). | +| โœ… | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. | +| โœ… | [Logging](#logging) | Integrate with popular logging packages. | +| โœ… | [Named clients](#named-clients) | Utilize multiple providers in a single application. | +| โŒ | [Eventing](#eventing) | React to state changes in the provider or flag management system. | +| โœ… | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. | +| โœ… | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. | + +Implemented: โœ… | In-progress: โš ๏ธ | Not implemented yet: โŒ + +### Providers + +[Providers](https://openfeature.dev/docs/reference/concepts/provider) are an abstraction between a flag management system and the OpenFeature SDK. +Here is [a complete list of available providers](https://openfeature.dev/ecosystem?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Provider&instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=.NET). + +If the provider you're looking for hasn't been created yet, see the [develop a provider](#develop-a-provider) section to learn how to build it yourself. + +Once you've added a provider as a dependency, it can be registered with OpenFeature like this: + +```csharp +await Api.Instance.SetProvider(new MyProvider()); +``` + +In some situations, it may be beneficial to register multiple providers in the same application. +This is possible using [named clients](#named-clients), which is covered in more detail below. + +### Targeting + +Sometimes, the value of a flag must consider some dynamic criteria about the application or user such as the user's location, IP, email address, or the server's location. +In OpenFeature, we refer to this as [targeting](https://openfeature.dev/specification/glossary#targeting). +If the flag management system you're using supports targeting, you can provide the input data using the [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). + +```csharp +// set a value to the global context +EvaluationContextBuilder builder = EvaluationContext.Builder(); +builder.Set("region", "us-east-1"); +EvaluationContext apiCtx = builder.Build(); +Api.Instance.SetContext(apiCtx); + +// set a value to the client context +builder = EvaluationContext.Builder(); +builder.Set("region", "us-east-1"); +EvaluationContext clientCtx = builder.Build(); +var client = Api.Instance.GetClient(); +client.SetContext(clientCtx); + +// set a value to the invocation context +builder = EvaluationContext.Builder(); +builder.Set("region", "us-east-1"); +EvaluationContext reqCtx = builder.Build(); + +bool flagValue = await client.GetBooleanValue("some-flag", false, reqCtx); + +``` + +### Hooks + +[Hooks](https://openfeature.dev/docs/reference/concepts/hooks) allow for custom logic to be added at well-defined points of the flag evaluation life-cycle. +Here is [a complete list of available hooks](https://openfeature.dev/docs/reference/technologies/server/dotnet/). +If the hook you're looking for hasn't been created yet, see the [develop a hook](#develop-a-hook) section to learn how to build it yourself. + +Once you've added a hook as a dependency, it can be registered at the global, client, or flag invocation level. + +```csharp +// add a hook globally, to run on all evaluations +Api.Instance.AddHooks(new ExampleGlobalHook()); + +// add a hook on this client, to run on all evaluations made by this client +var client = Api.Instance.GetClient(); +client.AddHooks(new ExampleClientHook()); + +// add a hook for this evaluation only +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 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. + +```csharp +// Shut down all providers +await Api.Instance.Shutdown(); +``` + +## Extending + +### Develop a provider + +To develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency. +This can be a new repository or included in [the existing contrib repository](https://github.com/open-feature/dotnet-sdk-contrib) available under the OpenFeature organization. +Youโ€™ll then need to write the provider by implementing the `FeatureProvider` interface exported by the OpenFeature SDK. + +```csharp +public class MyProvider : FeatureProvider + { + public override Metadata GetMetadata() + { + return new Metadata("My Provider"); + } + + public override Task> ResolveBooleanValue(string flagKey, bool defaultValue, EvaluationContext context = null) + { + // resolve a boolean flag value + } + + public override Task> ResolveDoubleValue(string flagKey, double defaultValue, EvaluationContext context = null) + { + // resolve a double flag value + } + + public override Task> ResolveIntegerValue(string flagKey, int defaultValue, EvaluationContext context = null) + { + // resolve an int flag value + } + + public override Task> ResolveStringValue(string flagKey, string defaultValue, EvaluationContext context = null) + { + // resolve a string flag value + } + + public override Task> ResolveStructureValue(string flagKey, Value defaultValue, EvaluationContext context = null) + { + // resolve an object flag value + } + } +``` + +### Develop a hook + +To develop a hook, you need to create a new project and include the OpenFeature SDK as a dependency. +This can be a new repository or included in [the existing contrib repository](https://github.com/open-feature/dotnet-sdk-contrib) available under the OpenFeature organization. +Implement your own hook by conforming to the `Hook interface`. +To satisfy the interface, all methods (`Before`/`After`/`Finally`/`Error`) need to be defined. + +```csharp +public class MyHook : Hook +{ + public Task Before(HookContext context, + IReadOnlyDictionary hints = null) + { + // code to run before flag evaluation + } + + public virtual Task After(HookContext context, FlagEvaluationDetails details, + IReadOnlyDictionary hints = null) + { + // code to run after successful flag evaluation + } + + public virtual Task Error(HookContext context, Exception error, + IReadOnlyDictionary hints = null) + { + // code to run if there's an error during before hooks or during flag evaluation + } + + public virtual Task Finally(HookContext context, IReadOnlyDictionary hints = null) + { + // code to run after all other stages, regardless of success/failure + } +} +``` + +Built a new hook? [Let us know](https://github.com/open-feature/openfeature.dev/issues/new?assignees=&labels=hook&projects=&template=document-hook.yaml&title=%5BHook%5D%3A+) so we can add it to the docs! + + +## โญ๏ธ Support the project + +- Give this repo a โญ๏ธ! +- Follow us on social media: + - Twitter: [@openfeature](https://twitter.com/openfeature) + - LinkedIn: [OpenFeature](https://www.linkedin.com/company/openfeature/) +- Join us on [Slack](https://cloud-native.slack.com/archives/C0344AANLA1) +- For more information, check out our [community page](https://openfeature.dev/community/) + +## ๐Ÿค Contributing + +Interested in contributing? Great, we'd love your help! To get started, take a look at the [CONTRIBUTING](CONTRIBUTING.md) guide. + +### Thanks to everyone who has already contributed + + + + + +Made with [contrib.rocks](https://contrib.rocks). + diff --git a/build/Common.prod.props b/build/Common.prod.props index 49e454c5..bd9d1aea 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -6,7 +6,7 @@ - 1.3.1 + 2.0.0 git https://github.com/open-feature/dotnet-sdk OpenFeature is an open standard for feature flag management, created to support a robust feature flag ecosystem using cloud native technologies. OpenFeature will provide a unified API and SDK, and a developer-first, cloud-native implementation, with extensibility for open source and commercial offerings. diff --git a/version.txt b/version.txt index 3a3cd8cc..227cea21 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.3.1 +2.0.0