feat: Add plugin support to Client SDK#229
Merged
abelonogov-ld merged 12 commits intomainfrom Mar 3, 2026
Merged
Conversation
…ailable before registration
tanderson-ld
requested changes
Feb 27, 2026
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
tanderson-ld
approved these changes
Mar 3, 2026
abelonogov-ld
pushed a commit
that referenced
this pull request
Mar 3, 2026
🤖 I have created a release *beep* *boop* --- ## [5.6.0](LaunchDarkly.ClientSdk-v5.5.4...LaunchDarkly.ClientSdk-v5.6.0) (2026-03-03) ### Features * Add plugin support to Client SDK ([#229](#229)) ([ce5cdd9](ce5cdd9)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is generating a summary for commit 2c47172. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
evgenygunko
pushed a commit
to evgenygunko/CopyWordsDA
that referenced
this pull request
Mar 4, 2026
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [LaunchDarkly.ClientSdk](https://github.com/launchdarkly/dotnet-core) | nuget | minor | `5.5.4` -> `5.6.0` | --- ### Release Notes <details> <summary>launchdarkly/dotnet-core (LaunchDarkly.ClientSdk)</summary> ### [`v5.6.0`](https://github.com/launchdarkly/dotnet-core/releases/tag/LaunchDarkly.ClientSdk-v5.6.0): LaunchDarkly.ClientSdk: v5.6.0 [Compare Source](launchdarkly/dotnet-core@LaunchDarkly.ClientSdk-v5.5.4...LaunchDarkly.ClientSdk-v5.6.0) ##### Features - Add plugin support to Client SDK ([#​229](launchdarkly/dotnet-core#229)) ([ce5cdd9](launchdarkly/dotnet-core@ce5cdd9)) *** This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). <!-- CURSOR_SUMMARY --> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or PR is renamed to start with "rebase!". 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
abelonogov-ld
added a commit
that referenced
this pull request
Mar 5, 2026
* main: chore(main): release LaunchDarkly.ServerSdk.Ai 0.9.3 (#233) fix: Make defaultValue optional with a disabled default (#232) chore(main): release LaunchDarkly.ClientSdk 5.6.0 (#231) feat: Add plugin support to Client SDK (#229) # Conflicts: # pkgs/sdk/client/src/Internal/Hooks/Executor/Executor.cs
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds plugin architecture and hook-based flag evaluation lifecycle support to the LaunchDarkly Client SDK for .NET, ported from the Server SDK implementation.
Plugin System
Pluginbase class (Plugins/Plugin.cs) that provides aGetHooks()method, allowing plugins to register hooks with the SDKPluginConfigurationandPluginConfigurationBuilderto configure plugins viaConfigurationBuilder.Plugins()LdClientto initialize plugins during startup, collect their hooks, and dispose of them properly during shutdownLdClientcleanup logic to ensure proper disposal order of resourcesHook Framework
Hookbase class with virtualBeforeEvaluation,AfterEvaluation,BeforeIdentify, andAfterIdentifystage methods, plusIDisposablesupportEvaluationSeriesContext- captures flag key, context, default value, method, and environment ID for evaluation hooksIdentifySeriesContext/IdentifySeriesResult- context and result types for identify hooksMethodconstants mapping to SDK variation methods (e.g.LdClient.BoolVariation)SeriesDataBuilder- fluent API for building immutable series data passed between hook stagesHook Execution Engine
Executor/NoopExecutorimplementingIHookExecutor- manages hook lifecycle with proper forward/reverse orderingBeforeEvaluation/AfterEvaluationstage executors with error isolation - exceptions in one hook do not prevent other hooks from executingLdClient.EvaluateInternal(), wrapping flag evaluations withBeforeEvaluationandAfterEvaluationcallsGetMethodName<T>()to resolve the correctMethodconstant based on variation type and detail modeEvaluateInternaldirectly, avoiding recursive hook invocationsTest Plan
EvaluationSeriesTest- hooks execute in LIFO order (forward before, reverse after)EvaluationSeriesTest- exceptions in hook stages don't prevent other hooks from runningEvaluationSeriesTest- stage failures log expected error messages with flag key and hook nameEvaluationSeriesTest- disposing executor disposes all registered hooksPluginConfigurationBuilderTest- plugin configuration builder tests passLdClientPluginTests- end-to-end plugin/hook integration tests passdotnet test --filter EvaluationSeriesTest)Note
Medium Risk
Touches core
LdClientevaluation flow by wrapping allVariation*calls with hook execution and adds plugin registration at startup, so regressions could affect flag evaluation behavior/performance despite safeguards like noop execution when unconfigured.Overview
Adds client-side plugin support by introducing
PluginConfigurationBuilder/PluginConfigurationand wiring a newPlugins(...)option throughComponents,ConfigurationBuilder, andConfiguration.Integrates plugin lifecycle into
LdClientinitialization: builds plugin config, createsEnvironmentMetadata, collects plugin-providedHooks, instantiates a hookExecutor(orNoopExecutorwhen none), then registers plugins; hook execution is disposed with the client and logs under a newLogNames.HooksSubLog.Introduces a hook API and execution pipeline for evaluations (
Hook,EvaluationSeriesContext, stage executors) and wrapsVariationInternalso hooks run before/after evaluations; prerequisite evaluations are refactored to callEvaluateInternaldirectly to avoid triggering hooks. Adds unit tests covering hook ordering/error isolation/disposal and plugin builder/registration behavior.Written by Cursor Bugbot for commit e5d9dc0. This will update automatically on new commits. Configure here.
Example of API