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 317589606..01a535e04 100644 --- a/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs +++ b/src/OpenFeature.DependencyInjection/OpenFeatureBuilderExtensions.cs @@ -278,6 +278,33 @@ 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 + { + return builder.AddHook(hookName, _ => hook); + } + /// /// Adds a feature hook to the service collection using a factory method and specified name. Hooks added here are not domain-bound. /// 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() {