From 20c83b364fa231496c52b90ec01725233adf814c Mon Sep 17 00:00:00 2001 From: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com> Date: Sat, 5 Jul 2025 21:20:29 +0100 Subject: [PATCH 1/4] Add additional Hook extension method Signed-off-by: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com> --- .../OpenFeatureBuilderExtensions.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs b/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs index 317589606..4ad544c4d 100644 --- a/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs +++ b/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs @@ -278,6 +278,37 @@ public static OpenFeatureBuilder AddHook(this OpenFeatureBuilder builder, return builder.AddHook(typeof(THook).Name, implementationFactory); } + /// + /// Adds a feature hook to the service collection. Hooks added here are not domain-bound. + /// + /// The type of to be added. + /// The instance. + /// Instance of Hook to inject into the OpenFeature context. + /// The instance. + public static OpenFeatureBuilder AddHook(this OpenFeatureBuilder builder, THook hook) + where THook : Hook + { + return builder.AddHook(typeof(THook).Name, _ => hook); + } + + /// + /// Adds a feature hook to the service collection with a specified name. Hooks added here are not domain-bound. + /// + /// The type of to be added. + /// The instance. + /// The name of the that is being added. + /// Instance of Hook to inject into the OpenFeature context. + /// The instance. + public static OpenFeatureBuilder AddHook(this OpenFeatureBuilder builder, string hookName, THook hook) + where THook : Hook + { + builder.Services.PostConfigure(options => options.AddHookName(hookName)); + + builder.Services.TryAddKeyedSingleton(hook); + + return builder; + } + /// /// Adds a feature hook to the service collection using a factory method and specified name. Hooks added here are not domain-bound. /// From ab6cf453fe6ccab43d1248a603d7b2e48c7b8e09 Mon Sep 17 00:00:00 2001 From: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com> Date: Sun, 6 Jul 2025 13:49:54 +0100 Subject: [PATCH 2/4] Add unit tests for new AddHook extension method Signed-off-by: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com> --- .../OpenFeatureBuilderExtensions.cs | 2 +- .../OpenFeatureBuilderExtensionsTests.cs | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs b/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs index 4ad544c4d..cf5b26683 100644 --- a/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs +++ b/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs @@ -304,7 +304,7 @@ public static OpenFeatureBuilder AddHook(this OpenFeatureBuilder builder, { builder.Services.PostConfigure(options => options.AddHookName(hookName)); - builder.Services.TryAddKeyedSingleton(hook); + builder.Services.TryAddKeyedSingleton(hookName, hook); return builder; } diff --git a/test/OpenFeature.DependencyInjection.Tests/OpenFeatureBuilderExtensionsTests.cs b/test/OpenFeature.DependencyInjection.Tests/OpenFeatureBuilderExtensionsTests.cs index f1edca4c4..f7cce0dfc 100644 --- a/test/OpenFeature.DependencyInjection.Tests/OpenFeatureBuilderExtensionsTests.cs +++ b/test/OpenFeature.DependencyInjection.Tests/OpenFeatureBuilderExtensionsTests.cs @@ -302,6 +302,40 @@ public void AddHook_WithSpecifiedNameAndImplementationFactory_AsKeyedService() Assert.NotNull(hook); } + [Fact] + public void AddHook_WithInstance_AddsHookAsKeyedService() + { + // Arrange + var expectedHook = new NoOpHook(); + _systemUnderTest.AddHook(expectedHook); + + var serviceProvider = _services.BuildServiceProvider(); + + // Act + var actualHook = serviceProvider.GetKeyedService("NoOpHook"); + + // Assert + Assert.NotNull(actualHook); + Assert.Equal(expectedHook, actualHook); + } + + [Fact] + public void AddHook_WithSpecifiedNameAndInstance_AddsHookAsKeyedService() + { + // Arrange + var expectedHook = new NoOpHook(); + _systemUnderTest.AddHook("custom-hook", expectedHook); + + var serviceProvider = _services.BuildServiceProvider(); + + // Act + var actualHook = serviceProvider.GetKeyedService("custom-hook"); + + // Assert + Assert.NotNull(actualHook); + Assert.Equal(expectedHook, actualHook); + } + [Fact] public void AddHandler_AddsEventHandlerDelegateWrapperAsKeyedService() { From b486abaa6b58dbf8bf42ab159d3f84b19a565b58 Mon Sep 17 00:00:00 2001 From: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com> Date: Sun, 6 Jul 2025 13:58:20 +0100 Subject: [PATCH 3/4] Chain AddHook to avoid unnecessary delegate and update README Signed-off-by: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com> --- README.md | 1 + .../OpenFeatureBuilderExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 66a3d620c..d51bfdc4d 100644 --- a/README.md +++ b/README.md @@ -481,6 +481,7 @@ builder.Services.AddOpenFeature(featureBuilder => { .AddHostedFeatureLifecycle() .AddContext((contextBuilder, serviceProvider) => { /* Custom context configuration */ }) .AddHook((serviceProvider) => new LoggingHook( /* Custom configuration */ )) + .AddHook(new MetricsHook()) .AddInMemoryProvider("name1") .AddInMemoryProvider("name2") .AddPolicyName(options => { diff --git a/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs b/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs index cf5b26683..0d7c7790f 100644 --- a/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs +++ b/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs @@ -288,7 +288,7 @@ public static OpenFeatureBuilder AddHook(this OpenFeatureBuilder builder, public static OpenFeatureBuilder AddHook(this OpenFeatureBuilder builder, THook hook) where THook : Hook { - return builder.AddHook(typeof(THook).Name, _ => hook); + return builder.AddHook(typeof(THook).Name, hook); } /// From 07e174ba1d1b323dc9b65d473572d20e1337c3e7 Mon Sep 17 00:00:00 2001 From: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com> Date: Sat, 12 Jul 2025 20:09:13 +0100 Subject: [PATCH 4/4] Simplify new AddHook extension by chaining Signed-off-by: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com> --- .../OpenFeatureBuilderExtensions.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs b/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs index 0d7c7790f..01a535e04 100644 --- a/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs +++ b/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs @@ -302,11 +302,7 @@ public static OpenFeatureBuilder AddHook(this OpenFeatureBuilder builder, public static OpenFeatureBuilder AddHook(this OpenFeatureBuilder builder, string hookName, THook hook) where THook : Hook { - builder.Services.PostConfigure(options => options.AddHookName(hookName)); - - builder.Services.TryAddKeyedSingleton(hookName, hook); - - return builder; + return builder.AddHook(hookName, _ => hook); } ///