From 9eb9e6ffef7f89484209067e19a7e70ef6020bb2 Mon Sep 17 00:00:00 2001 From: martincostello Date: Mon, 12 Apr 2021 12:12:04 +0100 Subject: [PATCH 1/2] Update Polly version Update Polly dependency to the latest version of the package. Addresses #31705. --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 7f1671a8e6d3..82a5d7de7ea9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -246,7 +246,7 @@ 13.0.4 0.192.0 3.0.0 - 7.1.0 + 7.2.2 4.0.0-beta1 89.0.4389.2300-beta 4.0.0-beta1 From 5a3193ea8a6921b4daf21ea9352a8debd2be5c5d Mon Sep 17 00:00:00 2001 From: martincostello Date: Mon, 12 Apr 2021 12:31:14 +0100 Subject: [PATCH 2/2] Add support for IConcurrentPolicyRegistry Also register Polly policies as IConcurrentPolicyRegistry. Addresses https://github.com/dotnet/aspnetcore/pull/28283#discussion_r598061746. --- .../PollyServiceCollectionExtensions.cs | 26 ++++++--- .../PollyHttpClientBuilderExtensionsTest.cs | 55 +++++++++++++++++++ 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/src/HttpClientFactory/Polly/src/DependencyInjection/PollyServiceCollectionExtensions.cs b/src/HttpClientFactory/Polly/src/DependencyInjection/PollyServiceCollectionExtensions.cs index 6fe049d11724..c9e080c4faf9 100644 --- a/src/HttpClientFactory/Polly/src/DependencyInjection/PollyServiceCollectionExtensions.cs +++ b/src/HttpClientFactory/Polly/src/DependencyInjection/PollyServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,15 +8,15 @@ namespace Microsoft.Extensions.DependencyInjection { /// - /// Provides convenience extension methods to register and - /// in the service collection. + /// Provides convenience extension methods to register and + /// in the service collection. /// public static class PollyServiceCollectionExtensions { /// /// Registers an empty in the service collection with service types - /// , and and returns - /// the newly created registry. + /// , , and + /// and returns the newly created registry. /// /// The . /// The newly created . @@ -30,6 +30,8 @@ public static IPolicyRegistry AddPolicyRegistry(this IServiceCollection // Create an empty registry, register and return it as an instance. This is the best way to get a // single instance registered using both interfaces. var registry = new PolicyRegistry(); + + services.AddSingleton>(registry); services.AddSingleton>(registry); services.AddSingleton>(registry); @@ -38,8 +40,8 @@ public static IPolicyRegistry AddPolicyRegistry(this IServiceCollection /// /// Registers the provided in the service collection with service types - /// , and and returns - /// the provided registry. + /// , , and + /// and returns the provided registry. /// /// The . /// The . @@ -59,13 +61,18 @@ public static IPolicyRegistry AddPolicyRegistry(this IServiceCollection services.AddSingleton>(registry); services.AddSingleton>(registry); + if (registry is IConcurrentPolicyRegistry concurrentRegistry) + { + services.AddSingleton>(concurrentRegistry); + } + return registry; } /// /// Registers an empty in the service collection with service types - /// , and and - /// uses the specified delegate to configure it. + /// , , and + /// and uses the specified delegate to configure it. /// /// The . /// A delegate that is used to configure an . @@ -93,6 +100,7 @@ public static IServiceCollection AddPolicyRegistry(this IServiceCollection servi return registry; }); + services.AddSingleton>(serviceProvider => serviceProvider.GetRequiredService()); services.AddSingleton>(serviceProvider => serviceProvider.GetRequiredService()); services.AddSingleton>(serviceProvider => serviceProvider.GetRequiredService()); diff --git a/src/HttpClientFactory/Polly/test/DependencyInjection/PollyHttpClientBuilderExtensionsTest.cs b/src/HttpClientFactory/Polly/test/DependencyInjection/PollyHttpClientBuilderExtensionsTest.cs index 94d3f82bfdf2..0f30410379de 100644 --- a/src/HttpClientFactory/Polly/test/DependencyInjection/PollyHttpClientBuilderExtensionsTest.cs +++ b/src/HttpClientFactory/Polly/test/DependencyInjection/PollyHttpClientBuilderExtensionsTest.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.Http; using Microsoft.Extensions.Http.Logging; using Polly; +using Polly.Registry; using Xunit; namespace Microsoft.Extensions.DependencyInjection @@ -468,6 +469,60 @@ public async Task AddPolicyHandlerFromRegistry_WithConfigureDelegate_AddsPolicyH Assert.Equal(HttpStatusCode.Created, response.StatusCode); } + [Fact] + public void AddPolicyHandlerFromRegistry_WithoutConfigureDelegate_AddsPolicyRegistries() + { + var serviceCollection = new ServiceCollection(); + + // Act + serviceCollection.AddPolicyRegistry(); + + var services = serviceCollection.BuildServiceProvider(); + var registry = services.GetService>(); + + // Assert + Assert.NotNull(registry); + Assert.Same(registry, services.GetService>()); + Assert.Same(registry, services.GetService>()); + } + + [Fact] + public void AddPolicyHandlerFromRegistry_WithRegistry_AddsPolicyRegistries() + { + var serviceCollection = new ServiceCollection(); + var registry = new PolicyRegistry(); + + // Act + serviceCollection.AddPolicyRegistry(registry); + + var services = serviceCollection.BuildServiceProvider(); + + // Assert + Assert.Same(registry, services.GetService>()); + Assert.Same(registry, services.GetService>()); + Assert.Same(registry, services.GetService>()); + } + + [Fact] + public void AddPolicyHandlerFromRegistry_WithConfigureDelegate_AddsPolicyRegistries() + { + var serviceCollection = new ServiceCollection(); + + // Act + serviceCollection.AddPolicyRegistry((serviceProvider, registry) => + { + // No-op + }); + + var services = serviceCollection.BuildServiceProvider(); + var registry = services.GetService>(); + + // Assert + Assert.NotNull(registry); + Assert.Same(registry, services.GetService>()); + Assert.Same(registry, services.GetService>()); + } + // Throws an exception or fails on even numbered requests, otherwise succeeds. private class FaultyMessageHandler : DelegatingHandler {