From 7b85c4f51a72ccad92fa6e5343b791356b4b3eb1 Mon Sep 17 00:00:00 2001 From: martintmk Date: Tue, 28 Mar 2023 07:52:15 +0200 Subject: [PATCH 01/12] Introduce Polly.Hosting project --- eng/Common.targets | 5 +- src/Directory.Packages.props | 16 +- .../ResilienceStrategyBuilderOptionsTests.cs | 22 ++ .../ResilienceStrategyBuilderOptions.cs | 28 +++ src/Polly.Core/Polly.Core.csproj | 3 +- .../Polly.Hosting.Tests.csproj | 20 ++ .../PollyServiceCollectionExtensionTests.cs | 209 ++++++++++++++++++ .../AddResilienceStrategyContext.cs | 34 +++ ...figureResilienceStrategyRegistryOptions.cs | 9 + .../PollyDependencyInjectionKeys.cs | 14 ++ .../PollyServiceCollectionExtensions.cs | 126 +++++++++++ src/Polly.Hosting/Polly.Hosting.csproj | 29 +++ src/Polly.Hosting/README.md | 38 ++++ src/Polly.sln | 13 ++ src/Polly/Polly.csproj | 2 +- src/{Polly.Core/Utils => Shared}/Guard.cs | 0 16 files changed, 564 insertions(+), 4 deletions(-) create mode 100644 src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj create mode 100644 src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs create mode 100644 src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs create mode 100644 src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs create mode 100644 src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs create mode 100644 src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs create mode 100644 src/Polly.Hosting/Polly.Hosting.csproj create mode 100644 src/Polly.Hosting/README.md rename src/{Polly.Core/Utils => Shared}/Guard.cs (100%) diff --git a/eng/Common.targets b/eng/Common.targets index e4b94f0dba5..08bd8def35f 100644 --- a/eng/Common.targets +++ b/eng/Common.targets @@ -16,5 +16,8 @@ - + + + + diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 26be7691315..6c7f5f4d342 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -6,6 +6,7 @@ + @@ -13,9 +14,22 @@ + - + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Polly.Core.Tests/Builder/ResilienceStrategyBuilderOptionsTests.cs b/src/Polly.Core.Tests/Builder/ResilienceStrategyBuilderOptionsTests.cs index 5564e29921d..1b7b1952816 100644 --- a/src/Polly.Core.Tests/Builder/ResilienceStrategyBuilderOptionsTests.cs +++ b/src/Polly.Core.Tests/Builder/ResilienceStrategyBuilderOptionsTests.cs @@ -1,3 +1,4 @@ +using Moq; using Polly.Builder; using Polly.Telemetry; using Polly.Utils; @@ -16,4 +17,25 @@ public void Ctor_EnsureDefaults() options.TimeProvider.Should().Be(TimeProvider.System); options.TelemetryFactory.Should().Be(NullResilienceTelemetryFactory.Instance); } + + [Fact] + public void Ctor_Copy_EnsureCopied() + { + var options = new ResilienceStrategyBuilderOptions + { + BuilderName = "test", + TelemetryFactory = Mock.Of(), + TimeProvider = new FakeTimeProvider().Object + }; + + options.Properties.Set(new ResiliencePropertyKey("A"), 1); + options.Properties.Set(new ResiliencePropertyKey("B"), 2); + + var other = new ResilienceStrategyBuilderOptions(options); + + other.BuilderName.Should().Be("test"); + other.TelemetryFactory.Should().BeSameAs(options.TelemetryFactory); + other.TimeProvider.Should().BeSameAs(options.TimeProvider); + other.Properties.Should().BeEquivalentTo(options.Properties); + } } diff --git a/src/Polly.Core/Builder/ResilienceStrategyBuilderOptions.cs b/src/Polly.Core/Builder/ResilienceStrategyBuilderOptions.cs index eb514f0e30e..5d8fdcbde11 100644 --- a/src/Polly.Core/Builder/ResilienceStrategyBuilderOptions.cs +++ b/src/Polly.Core/Builder/ResilienceStrategyBuilderOptions.cs @@ -1,3 +1,4 @@ +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using Polly.Telemetry; @@ -8,6 +9,33 @@ namespace Polly.Builder; /// public class ResilienceStrategyBuilderOptions { + /// + /// Initializes a new instance of the class. + /// + public ResilienceStrategyBuilderOptions() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The options to copy the values from. + [EditorBrowsable(EditorBrowsableState.Never)] + public ResilienceStrategyBuilderOptions(ResilienceStrategyBuilderOptions other) + { + Guard.NotNull(other); + + BuilderName = other.BuilderName; + TelemetryFactory = other.TelemetryFactory; + TimeProvider = other.TimeProvider; + + var dict = (IDictionary)Properties; + foreach (KeyValuePair pair in other.Properties) + { + dict.Add(pair.Key, pair.Value); + } + } + /// /// Gets or sets the name of the builder. /// diff --git a/src/Polly.Core/Polly.Core.csproj b/src/Polly.Core/Polly.Core.csproj index 6c649319ef2..74de2dfa1f0 100644 --- a/src/Polly.Core/Polly.Core.csproj +++ b/src/Polly.Core/Polly.Core.csproj @@ -1,7 +1,7 @@  - net7.0;net6.0;netstandard2.0;net472;net461 + net7.0;net6.0;netstandard2.0;net472;net462 Polly.Core Polly enable @@ -11,6 +11,7 @@ true 100 true + true diff --git a/src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj b/src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj new file mode 100644 index 00000000000..6985acfe008 --- /dev/null +++ b/src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj @@ -0,0 +1,20 @@ + + + net7.0;net6.0 + $(TargetFrameworks);net481 + Test + true + enable + true + 100 + $(NoWarn);SA1600;SA1204 + [Polly.Core]* + + + + + + + + + diff --git a/src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs b/src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs new file mode 100644 index 00000000000..2d92d797cd9 --- /dev/null +++ b/src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs @@ -0,0 +1,209 @@ +using System; +using System.Globalization; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Moq; +using Polly.Builder; +using Polly.DependencyInjection; +using Polly.Registry; +using Polly.Telemetry; + +namespace Polly.Hosting.Tests; +public class PollyServiceCollectionExtensionTests +{ + private const string Key = "my-strategy"; + private ServiceCollection _services; + + public PollyServiceCollectionExtensionTests() => _services = new ServiceCollection(); + + [Fact] + public void AddResilienceStrategy_ArgValidation() + { + _services = null!; + Assert.Throws(() => AddResilienceStrategy(Key)); + + _services = new ServiceCollection(); + Assert.Throws(() => _services.AddResilienceStrategy(Key, null!)); + } + + [Fact] + public void AddResilienceStrategy_EnsureRegisteredServices() + { + AddResilienceStrategy(Key); + + var serviceProvider = _services.BuildServiceProvider(); + + serviceProvider.GetServices().Should().NotBeNull(); + serviceProvider.GetServices>().Should().NotBeNull(); + serviceProvider.GetServices>().Should().NotBeNull(); + serviceProvider.GetServices().Should().NotBeSameAs(serviceProvider.GetServices()); + } + + [Fact] + public void AddResilienceStrategy_MultipleRegistries_Ok() + { + AddResilienceStrategy(Key); + _services.AddResilienceStrategy(10, context => context.Builder.AddStrategy(new TestStrategy())); + + var serviceProvider = _services.BuildServiceProvider(); + + serviceProvider.GetRequiredService>().Get(Key).Should().NotBeNull(); + serviceProvider.GetRequiredService>().Get(10).Should().NotBeNull(); + } + + [Fact] + public void AddResilienceStrategy_EnsureContextFilled() + { + bool asserted = false; + + _services.AddResilienceStrategy(Key, context => + { + context.Key.Should().Be(Key); + context.Builder.Should().NotBeNull(); + context.ServiceProvider.Should().NotBeNull(); + context.Builder.AddStrategy(new TestStrategy()); + asserted = true; + }); + + CreateProvider().Get(Key); + + asserted.Should().BeTrue(); + } + + [Fact] + public void AddResilienceStrategy_EnsureResilienceStrategyBuilderOptionsApplied() + { + var telemetry = Mock.Of(); + var telemetryFactory = Mock.Of(v => v.Create(It.IsAny()) == telemetry); + var asserted = false; + var key = new ResiliencePropertyKey("A"); + ResilienceStrategyBuilderOptions? globalOptions = null; + + _services.Configure(options => + { + options.BuilderName = "dummy"; + options.TelemetryFactory = telemetryFactory; + options.Properties.Set(key, 123); + globalOptions = options; + }); + + AddResilienceStrategy(Key, context => + { + context.BuilderProperties.Should().NotBeSameAs(globalOptions!.Properties); + context.BuilderName.Should().Be("dummy"); + context.Telemetry.Should().Be(telemetry); + context.BuilderProperties.TryGetValue(key, out var val).Should().BeTrue(); + val.Should().Be(123); + asserted = true; + }); + + CreateProvider().Get(Key); + + asserted.Should().BeTrue(); + } + + [Fact] + public void AddResilienceStrategy_EnsureServicesNotAddedTwice() + { + AddResilienceStrategy(Key); + var count = _services.Count; + + AddResilienceStrategy(Key); + + _services.Count.Should().Be(count + 1); + } + + [Fact] + public void AddResilienceStrategy_Single_Ok() + { + AddResilienceStrategy(Key); + + var provider = CreateProvider(); + + var strategy = provider.Get(Key); + strategy.Should().BeOfType(); + provider.Get("my-strategy").Should().BeSameAs(provider.Get("my-strategy")); + } + + [Fact] + public void AddResilienceStrategy_Twice_LastOneWins() + { + bool firstCalled = false; + bool secondCalled = false; + + AddResilienceStrategy(Key, _ => firstCalled = true); + AddResilienceStrategy(Key, _ => secondCalled = true); + + CreateProvider().Get(Key); + + firstCalled.Should().BeFalse(); + secondCalled.Should().BeTrue(); + } + + [Fact] + public void AddResilienceStrategy_Multiple_Ok() + { + for (int i = 0; i < 10; i++) + { + AddResilienceStrategy(i.ToString(CultureInfo.InvariantCulture)); + } + + var provider = CreateProvider(); + + Enumerable.Range(0, 10).Select(i => i.ToString(CultureInfo.InvariantCulture)).Distinct().Should().HaveCount(10); + } + + [Fact] + public void AddResilienceStrategy_CustomTelemetryFactory_EnsureUsed() + { + var telemetry = new Mock(MockBehavior.Strict); + var factory = new Mock(MockBehavior.Strict); + factory.Setup(v => v.Create(It.IsAny())).Returns(telemetry.Object); + + var asserted = false; + + _services.AddSingleton(factory.Object); + _services.AddResilienceStrategy( + Key, + context => + { + context.Builder.Options.TelemetryFactory.Should().Be(factory.Object); + context.Builder.AddStrategy(context => + { + context.Telemetry.Should().Be(telemetry.Object); + + asserted = true; + return new TestStrategy(); + }); + }); + + CreateProvider().Get(Key); + + asserted.Should().BeTrue(); + } + + private void AddResilienceStrategy(string key, Action? onBuilding = null) + { + _services.AddResilienceStrategy(key, context => + { + context.Builder.AddStrategy(context => + { + onBuilding?.Invoke(context); + return new TestStrategy(); + }); + }); + } + + private ResilienceStrategyProvider CreateProvider() + { + return _services.BuildServiceProvider().GetRequiredService>(); + } + + private class TestStrategy : ResilienceStrategy + { + protected override ValueTask ExecuteCoreAsync( + Func> callback, + ResilienceContext context, + TState state) => throw new NotSupportedException(); + } +} diff --git a/src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs b/src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs new file mode 100644 index 00000000000..a4858d22959 --- /dev/null +++ b/src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs @@ -0,0 +1,34 @@ +using System; +using Polly.Builder; + +namespace Polly.DependencyInjection; + +/// +/// Represents the context for adding a resilience strategy with the specified key. +/// +/// The type of the key used to identify the resilience strategy. +public sealed class AddResilienceStrategyContext + where TKey : notnull +{ + internal AddResilienceStrategyContext(TKey key, ResilienceStrategyBuilder builder, IServiceProvider serviceProvider) + { + Key = key; + Builder = builder; + ServiceProvider = serviceProvider; + } + + /// + /// Gets the key used to identify the resilience strategy. + /// + public TKey Key { get; } + + /// + /// Gets the used to build the resilience strategy. + /// + public ResilienceStrategyBuilder Builder { get; } + + /// + /// Gets the that provides access to the dependency injection container. + /// + public IServiceProvider ServiceProvider { get; } +} diff --git a/src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs b/src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs new file mode 100644 index 00000000000..d9fc9fb73d4 --- /dev/null +++ b/src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs @@ -0,0 +1,9 @@ +namespace Polly.DependencyInjection; + +internal class ConfigureResilienceStrategyRegistryOptions + where TKey : notnull +{ + public List Actions { get; } = new(); + + public record Entry(TKey Key, Action> Configure); +} diff --git a/src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs b/src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs new file mode 100644 index 00000000000..189a517fe01 --- /dev/null +++ b/src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs @@ -0,0 +1,14 @@ +using System; + +namespace Polly.DependencyInjection; + +/// +/// The resilience keys used in the dependency injection scenarios. +/// +public static class PollyDependencyInjectionKeys +{ + /// + /// The key used to store and access the from . + /// + public static readonly ResiliencePropertyKey ServiceProvider = new("Polly.DependencyInjection.ServiceProvider"); +} diff --git a/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs b/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs new file mode 100644 index 00000000000..1f982a99571 --- /dev/null +++ b/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; +using Polly.Builder; +using Polly.Registry; +using Polly.Telemetry; +using Polly.Utils; + +namespace Polly.DependencyInjection; + +/// +/// Provides extension methods for registering resilience strategies using the . +/// +public static class PollyServiceCollectionExtensions +{ + /// + /// Adds a resilience strategy to service collection. + /// + /// The type of the key used to identify the resilience strategy. + /// The to add the resilience strategy to. + /// The key used to identify the resilience strategy. + /// An action that configures the resilience strategy. + /// The updated with the registered resilience strategy. + /// Thrown if the resilience strategy builder with the provided key has already been added to the registry. + /// + /// You can retrieve the registered strategy by resolving the class from the dependency injection container. + /// + public static IServiceCollection AddResilienceStrategy( + this IServiceCollection services, + TKey key, + Action> configure) + where TKey : notnull + { + Guard.NotNull(services); + Guard.NotNull(configure); + + services.Configure>(options => + { + options.Actions.Add(new ConfigureResilienceStrategyRegistryOptions.Entry(key, configure)); + }); + + // check marker to ensure the APIs bellow are called only once for each TKey type + if (services.Contains(RegistryMarker.ServiceDescriptor)) + { + return services; + } + + services.Add(RegistryMarker.ServiceDescriptor); + services.AddResilienceStrategyBuilder(); + services.AddResilienceStrategyRegistry(); + + return services; + } + + private static IServiceCollection AddResilienceStrategyRegistry(this IServiceCollection services) + where TKey : notnull + { + services.TryAddSingleton(serviceProvider => + { + var options = serviceProvider.GetRequiredService>>().Value; + var configureActions = serviceProvider.GetRequiredService>>().Value.Actions; + var registry = new ResilienceStrategyRegistry(options); + + foreach (var entry in configureActions) + { + // last added builder with the same key always wins, this allows to overriding the registered builders + registry.RemoveBuilder(entry.Key); + registry.TryAddBuilder(entry.Key, (key, builder) => + { + var context = new AddResilienceStrategyContext(key, builder, serviceProvider); + entry.Configure(context); + }); + } + + return registry; + }); + + services.TryAddSingleton>(serviceProvider => + { + return serviceProvider.GetRequiredService>(); + }); + + // configure options + services + .AddOptions>() + .Configure((options, serviceProvider) => + { + options.BuilderFactory = () => serviceProvider.GetRequiredService(); + }); + + return services; + } + + private static void AddResilienceStrategyBuilder(this IServiceCollection services) + { + services + .AddOptions() + .PostConfigure((options, serviceProvider) => + { + if (options.TelemetryFactory == NullResilienceTelemetryFactory.Instance && + serviceProvider.GetService() is ResilienceTelemetryFactory factory) + { + options.TelemetryFactory = factory; + } + + options.Properties.Set(PollyDependencyInjectionKeys.ServiceProvider, serviceProvider); + }); + + services.TryAddTransient(serviceProvider => + { + var globalOptions = serviceProvider.GetRequiredService>().Value; + + return new ResilienceStrategyBuilder + { + Options = new ResilienceStrategyBuilderOptions(globalOptions) + }; + }); + } + + private class RegistryMarker + { + public static readonly ServiceDescriptor ServiceDescriptor = ServiceDescriptor.Singleton(new RegistryMarker()); + } +} diff --git a/src/Polly.Hosting/Polly.Hosting.csproj b/src/Polly.Hosting/Polly.Hosting.csproj new file mode 100644 index 00000000000..719edd34691 --- /dev/null +++ b/src/Polly.Hosting/Polly.Hosting.csproj @@ -0,0 +1,29 @@ + + + net7.0;net6.0;netstandard2.0;net472;net462 + Polly.Hosting + Polly + enable + true + Library + true + true + 100 + true + true + + + + + + + + + + + + + + + + diff --git a/src/Polly.Hosting/README.md b/src/Polly.Hosting/README.md new file mode 100644 index 00000000000..93dba0bfc70 --- /dev/null +++ b/src/Polly.Hosting/README.md @@ -0,0 +1,38 @@ +# About Polly.Hosting + +The `Polly.Hosting` enables the following features: + + +- Integrates the Polly with the standard `IServiceCollection` DI container. +- Implements the `ResilienceTelemetryFactory` that adds [logging](https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line) and [metering](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/metrics) for all strategies created using the DI extension points. + + +Example: + +``` csharp +var services = new ServiceCollection(); + +// define your strategy +services.AddResilienceStrategy( + "my-key", + context => context.Builder.AddTimeout(TimeSpan.FromSeconds(10))); + +// define your strategy using custom options +services.AddResilienceStrategy( + "my-timeout", + context => + { + var myOptions = context.ServiceProvider.GetRequiredService>().Value; + context.Builder.AddTimeout(myOptions.Timeout); + }); + +// use your strategy +var serviceProvider = services.BuildServiceProvider(); +var strategyProvider = serviceProvider.GetRequiredService>(); + +var resilienceStrategy = strategyProvider.Get("my-key"); + +// use your strategy +The consumer just calls the AddResilienceStrategy and provides a callback that configures the resilience strategy. +``` + diff --git a/src/Polly.sln b/src/Polly.sln index 3551a409021..f95bf1c3856 100644 --- a/src/Polly.sln +++ b/src/Polly.sln @@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\.github\workflows\build.yml = ..\.github\workflows\build.yml Directory.Build.props = Directory.Build.props Directory.Build.targets = Directory.Build.targets + Directory.Packages.props = Directory.Packages.props ..\GitVersionConfig.yaml = ..\GitVersionConfig.yaml ..\global.json = ..\global.json ..\README.md = ..\README.md @@ -37,6 +38,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "eng", "eng", "{04E3C7C5-31F EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Core.Benchmarks", "Polly.Core.Benchmarks\Polly.Core.Benchmarks.csproj", "{CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Hosting", "Polly.Hosting\Polly.Hosting.csproj", "{F2FDE6BF-DA86-4DDE-A55C-E2A064CD30D8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Hosting.Tests", "Polly.Hosting.Tests\Polly.Hosting.Tests.csproj", "{BB2843CA-B518-48A1-BAD9-B63238F21608}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -67,6 +72,14 @@ Global {CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}.Debug|Any CPU.Build.0 = Debug|Any CPU {CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}.Release|Any CPU.ActiveCfg = Release|Any CPU {CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}.Release|Any CPU.Build.0 = Release|Any CPU + {F2FDE6BF-DA86-4DDE-A55C-E2A064CD30D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2FDE6BF-DA86-4DDE-A55C-E2A064CD30D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2FDE6BF-DA86-4DDE-A55C-E2A064CD30D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2FDE6BF-DA86-4DDE-A55C-E2A064CD30D8}.Release|Any CPU.Build.0 = Release|Any CPU + {BB2843CA-B518-48A1-BAD9-B63238F21608}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB2843CA-B518-48A1-BAD9-B63238F21608}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB2843CA-B518-48A1-BAD9-B63238F21608}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB2843CA-B518-48A1-BAD9-B63238F21608}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Polly/Polly.csproj b/src/Polly/Polly.csproj index dd4d4255bb6..9cdd550c45b 100644 --- a/src/Polly/Polly.csproj +++ b/src/Polly/Polly.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net472;net461; + netstandard2.0;net472;net462; Polly Library 70 diff --git a/src/Polly.Core/Utils/Guard.cs b/src/Shared/Guard.cs similarity index 100% rename from src/Polly.Core/Utils/Guard.cs rename to src/Shared/Guard.cs From f84a5cedd19ae0d11c600b18683626f02a39f9ae Mon Sep 17 00:00:00 2001 From: martintmk Date: Tue, 28 Mar 2023 09:14:19 +0200 Subject: [PATCH 02/12] cleanup --- build.cake | 1 + src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj | 2 +- .../PollyDependencyInjectionKeysTests.cs | 12 ++++++++++++ .../PollyServiceCollectionExtensionTests.cs | 3 +-- 4 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 src/Polly.Hosting.Tests/PollyDependencyInjectionKeysTests.cs diff --git a/build.cake b/build.cake index de503ef98d5..45f13fb2958 100644 --- a/build.cake +++ b/build.cake @@ -216,6 +216,7 @@ Task("__RunMutationTests") .Does(() => { TestProject(File("./src/Polly.Core/Polly.Core.csproj"), File("./src/Polly.Core.Tests/Polly.Core.Tests.csproj"), "Polly.Core.csproj"); + TestProject(File("./src/Polly.Hosting/Polly.Hosting.csproj"), File("./src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj"), "Polly.Hosting.csproj"); TestProject(File("./src/Polly/Polly.csproj"), File("./src/Polly.Specs/Polly.Specs.csproj"), "Polly.csproj"); void TestProject(FilePath proj, FilePath testProj, string project) diff --git a/src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj b/src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj index 6985acfe008..cbafa2cf790 100644 --- a/src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj +++ b/src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj @@ -8,7 +8,7 @@ true 100 $(NoWarn);SA1600;SA1204 - [Polly.Core]* + [Polly.Hosting]* diff --git a/src/Polly.Hosting.Tests/PollyDependencyInjectionKeysTests.cs b/src/Polly.Hosting.Tests/PollyDependencyInjectionKeysTests.cs new file mode 100644 index 00000000000..f0faa5a9404 --- /dev/null +++ b/src/Polly.Hosting.Tests/PollyDependencyInjectionKeysTests.cs @@ -0,0 +1,12 @@ +using Polly.DependencyInjection; + +namespace Polly.Hosting.Tests; + +public class PollyDependencyInjectionKeysTests +{ + [Fact] + public void ServiceProvider_Ok() + { + PollyDependencyInjectionKeys.ServiceProvider.Key.Should().Be("Polly.DependencyInjection.ServiceProvider"); + } +} diff --git a/src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs b/src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs index 2d92d797cd9..efa0fd188a4 100644 --- a/src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs +++ b/src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs @@ -1,6 +1,4 @@ -using System; using System.Globalization; -using System.Linq; using Microsoft.Extensions.DependencyInjection; using Moq; using Polly.Builder; @@ -9,6 +7,7 @@ using Polly.Telemetry; namespace Polly.Hosting.Tests; + public class PollyServiceCollectionExtensionTests { private const string Key = "my-strategy"; From e16c8f18bd21462870610b7fd3eafcb24befc8cd Mon Sep 17 00:00:00 2001 From: martintmk Date: Tue, 28 Mar 2023 09:32:16 +0200 Subject: [PATCH 03/12] Fix the build? --- eng/Common.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Common.targets b/eng/Common.targets index 08bd8def35f..9cf969b22be 100644 --- a/eng/Common.targets +++ b/eng/Common.targets @@ -14,10 +14,10 @@ - + - + From 26cb3b1f610421310e04b1fb2d26f4503a62dfe3 Mon Sep 17 00:00:00 2001 From: martintmk Date: Tue, 28 Mar 2023 09:45:36 +0200 Subject: [PATCH 04/12] Build fixes --- eng/Common.targets | 4 ---- src/{Shared => Polly.Core/Utils}/Guard.cs | 0 src/Polly.Hosting/Polly.Hosting.csproj | 4 +++- 3 files changed, 3 insertions(+), 5 deletions(-) rename src/{Shared => Polly.Core/Utils}/Guard.cs (100%) diff --git a/eng/Common.targets b/eng/Common.targets index 9cf969b22be..3883e0b8f0d 100644 --- a/eng/Common.targets +++ b/eng/Common.targets @@ -16,8 +16,4 @@ - - - - diff --git a/src/Shared/Guard.cs b/src/Polly.Core/Utils/Guard.cs similarity index 100% rename from src/Shared/Guard.cs rename to src/Polly.Core/Utils/Guard.cs diff --git a/src/Polly.Hosting/Polly.Hosting.csproj b/src/Polly.Hosting/Polly.Hosting.csproj index 719edd34691..a44d658479d 100644 --- a/src/Polly.Hosting/Polly.Hosting.csproj +++ b/src/Polly.Hosting/Polly.Hosting.csproj @@ -10,8 +10,10 @@ true 100 true - true + + + From b7d1c9b53617d2977aec2fc7f8bb77e0c798e09a Mon Sep 17 00:00:00 2001 From: martintmk Date: Tue, 28 Mar 2023 10:04:23 +0200 Subject: [PATCH 05/12] comments --- .../DependencyInjection/PollyServiceCollectionExtensions.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs b/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs index 1f982a99571..51d51aa94f7 100644 --- a/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs +++ b/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs @@ -42,6 +42,7 @@ public static IServiceCollection AddResilienceStrategy( }); // check marker to ensure the APIs bellow are called only once for each TKey type + // this prevents polluting the service collection with unnecessary Configure calls if (services.Contains(RegistryMarker.ServiceDescriptor)) { return services; @@ -65,7 +66,7 @@ private static IServiceCollection AddResilienceStrategyRegistry(this IServ foreach (var entry in configureActions) { - // last added builder with the same key always wins, this allows to overriding the registered builders + // the last added builder with the same key wins, this allows overriding the builders registry.RemoveBuilder(entry.Key); registry.TryAddBuilder(entry.Key, (key, builder) => { From 7526464ae1f90e6ebe29b7c8f6d1b27671d2f8a1 Mon Sep 17 00:00:00 2001 From: martintmk Date: Tue, 28 Mar 2023 10:08:45 +0200 Subject: [PATCH 06/12] Cleanup --- src/Polly.Core/Builder/ResilienceStrategyBuilderOptions.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Polly.Core/Builder/ResilienceStrategyBuilderOptions.cs b/src/Polly.Core/Builder/ResilienceStrategyBuilderOptions.cs index 5d8fdcbde11..c0eabecc027 100644 --- a/src/Polly.Core/Builder/ResilienceStrategyBuilderOptions.cs +++ b/src/Polly.Core/Builder/ResilienceStrategyBuilderOptions.cs @@ -29,10 +29,11 @@ public ResilienceStrategyBuilderOptions(ResilienceStrategyBuilderOptions other) TelemetryFactory = other.TelemetryFactory; TimeProvider = other.TimeProvider; - var dict = (IDictionary)Properties; + IDictionary props = Properties; + foreach (KeyValuePair pair in other.Properties) { - dict.Add(pair.Key, pair.Value); + props.Add(pair.Key, pair.Value); } } From dd2b18eaf805cf7691dd6f6c377f859e55d27ba5 Mon Sep 17 00:00:00 2001 From: martintmk Date: Tue, 28 Mar 2023 11:08:05 +0200 Subject: [PATCH 07/12] PR comments --- .github/dependabot.yml | 3 +++ .../ConfigureResilienceStrategyRegistryOptions.cs | 2 +- .../PollyServiceCollectionExtensions.cs | 1 + src/Polly.Hosting/README.md | 15 +++++---------- src/Polly.sln | 1 + 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3bc9ad43e50..cc855d14637 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -19,3 +19,6 @@ updates: - dependency-name: "System.ComponentModel.Annotations" - dependency-name: "System.Threading.Tasks.Extensions" - dependency-name: "System.ValueTuplens" + - dependency-name: "Microsoft.Extensions.Options" + - dependency-name: "Microsoft.Extensions.Logging.Abstractions" + - dependency-name: "System.Diagnostics.DiagnosticSource" diff --git a/src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs b/src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs index d9fc9fb73d4..3e75fe8fb21 100644 --- a/src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs +++ b/src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs @@ -1,6 +1,6 @@ namespace Polly.DependencyInjection; -internal class ConfigureResilienceStrategyRegistryOptions +internal sealed class ConfigureResilienceStrategyRegistryOptions where TKey : notnull { public List Actions { get; } = new(); diff --git a/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs b/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs index 51d51aa94f7..8cb92a10f67 100644 --- a/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs +++ b/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs @@ -36,6 +36,7 @@ public static IServiceCollection AddResilienceStrategy( Guard.NotNull(services); Guard.NotNull(configure); + services.AddOptions(); services.Configure>(options => { options.Actions.Add(new ConfigureResilienceStrategyRegistryOptions.Entry(key, configure)); diff --git a/src/Polly.Hosting/README.md b/src/Polly.Hosting/README.md index 93dba0bfc70..a4eb701cf61 100644 --- a/src/Polly.Hosting/README.md +++ b/src/Polly.Hosting/README.md @@ -3,21 +3,20 @@ The `Polly.Hosting` enables the following features: -- Integrates the Polly with the standard `IServiceCollection` DI container. -- Implements the `ResilienceTelemetryFactory` that adds [logging](https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line) and [metering](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/metrics) for all strategies created using the DI extension points. - +- Integrates Polly with the standard `IServiceCollection` Dependency Injection (DI) container. +- Implements `ResilienceTelemetryFactory` that adds [logging](https://learn.microsoft.com/dotnet/core/extensions/logging?tabs=command-line) and [metering](https://learn.microsoft.com/dotnet/core/diagnostics/metrics) for all strategies created using the DI extension points. Example: ``` csharp var services = new ServiceCollection(); -// define your strategy +// Define your strategy services.AddResilienceStrategy( "my-key", context => context.Builder.AddTimeout(TimeSpan.FromSeconds(10))); -// define your strategy using custom options +// Define your strategy using custom options services.AddResilienceStrategy( "my-timeout", context => @@ -26,13 +25,9 @@ services.AddResilienceStrategy( context.Builder.AddTimeout(myOptions.Timeout); }); -// use your strategy +// Use your strategy var serviceProvider = services.BuildServiceProvider(); var strategyProvider = serviceProvider.GetRequiredService>(); - var resilienceStrategy = strategyProvider.Get("my-key"); - -// use your strategy -The consumer just calls the AddResilienceStrategy and provides a callback that configures the resilience strategy. ``` diff --git a/src/Polly.sln b/src/Polly.sln index f95bf1c3856..e9f4c21bd1a 100644 --- a/src/Polly.sln +++ b/src/Polly.sln @@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\eng\Analyzers.targets = ..\eng\Analyzers.targets ..\build.cake = ..\build.cake ..\.github\workflows\build.yml = ..\.github\workflows\build.yml + ..\.github\dependabot.yml = ..\.github\dependabot.yml Directory.Build.props = Directory.Build.props Directory.Build.targets = Directory.Build.targets Directory.Packages.props = Directory.Packages.props From 9bf37234ace9ada75ff6c8e7cd6c0d4a2af05070 Mon Sep 17 00:00:00 2001 From: martintmk Date: Tue, 28 Mar 2023 11:09:59 +0200 Subject: [PATCH 08/12] Cleanup --- .../DependencyInjection/AddResilienceStrategyContext.cs | 1 - .../DependencyInjection/PollyDependencyInjectionKeys.cs | 2 -- .../DependencyInjection/PollyServiceCollectionExtensions.cs | 2 -- 3 files changed, 5 deletions(-) diff --git a/src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs b/src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs index a4858d22959..af75f17db58 100644 --- a/src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs +++ b/src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs @@ -1,4 +1,3 @@ -using System; using Polly.Builder; namespace Polly.DependencyInjection; diff --git a/src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs b/src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs index 189a517fe01..69cfb201c1a 100644 --- a/src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs +++ b/src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs @@ -1,5 +1,3 @@ -using System; - namespace Polly.DependencyInjection; /// diff --git a/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs b/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs index 8cb92a10f67..e692229b12d 100644 --- a/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs +++ b/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs @@ -1,5 +1,3 @@ -using System; -using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; From da13f522df10d0bc260a75da0e4e07e1cc675fc1 Mon Sep 17 00:00:00 2001 From: martintmk Date: Tue, 28 Mar 2023 11:59:57 +0200 Subject: [PATCH 09/12] Kill mutant --- .../Utils/TimeProviderExtensionsTests.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Polly.Core.Tests/Utils/TimeProviderExtensionsTests.cs b/src/Polly.Core.Tests/Utils/TimeProviderExtensionsTests.cs index b85d0b5dceb..0335a4de968 100644 --- a/src/Polly.Core.Tests/Utils/TimeProviderExtensionsTests.cs +++ b/src/Polly.Core.Tests/Utils/TimeProviderExtensionsTests.cs @@ -38,12 +38,28 @@ await TestUtils.AssertWithTimeoutAsync(async () => } } + [Fact] + public async Task DelayAsync_SystemSynchronous_Ok() + { + var delay = TimeSpan.FromMilliseconds(5); + var context = ResilienceContext.Get(); + context.Initialize(isSynchronous: true); + + await TestUtils.AssertWithTimeoutAsync(async () => + { + var watch = Stopwatch.StartNew(); + await TimeProvider.System.DelayAsync(delay, context); + var elapsed = watch.Elapsed; + elapsed.Should().BeGreaterThanOrEqualTo(delay); + }); + } + [InlineData(false, false)] [InlineData(false, true)] [InlineData(true, false)] [InlineData(true, true)] [Theory] - public async Task DelayAsync_CancellationRequestedbefore_Throws(bool synchronous, bool mocked) + public async Task DelayAsync_CancellationRequestedBefore_Throws(bool synchronous, bool mocked) { using var tcs = new CancellationTokenSource(); tcs.Cancel(); From 24d0a8ea5a490511c81ca78738184396dad1c45c Mon Sep 17 00:00:00 2001 From: martintmk Date: Thu, 30 Mar 2023 08:45:18 +0200 Subject: [PATCH 10/12] Rename Polly.Hsoting to Polly.Extensions --- build.cake | 3 +++ .../PollyDependencyInjectionKeysTests.cs | 4 ++-- .../PollyServiceCollectionExtensionTests.cs | 14 +++++++------- .../Polly.Extensions.Tests.csproj} | 4 ++-- .../AddResilienceStrategyContext.cs | 2 +- .../ConfigureResilienceStrategyRegistryOptions.cs | 2 +- .../PollyDependencyInjectionKeys.cs | 2 +- .../PollyServiceCollectionExtensions.cs | 2 +- .../Polly.Extensions.csproj} | 6 +++--- src/{Polly.Hosting => Polly.Extensions}/README.md | 0 src/Polly.sln | 4 ++-- 11 files changed, 23 insertions(+), 20 deletions(-) rename src/{Polly.Hosting.Tests => Polly.Extensions.Tests/DependencyInjection}/PollyDependencyInjectionKeysTests.cs (69%) rename src/{Polly.Hosting.Tests => Polly.Extensions.Tests/DependencyInjection}/PollyServiceCollectionExtensionTests.cs (95%) rename src/{Polly.Hosting.Tests/Polly.Hosting.Tests.csproj => Polly.Extensions.Tests/Polly.Extensions.Tests.csproj} (83%) rename src/{Polly.Hosting => Polly.Extensions}/DependencyInjection/AddResilienceStrategyContext.cs (95%) rename src/{Polly.Hosting => Polly.Extensions}/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs (83%) rename src/{Polly.Hosting => Polly.Extensions}/DependencyInjection/PollyDependencyInjectionKeys.cs (90%) rename src/{Polly.Hosting => Polly.Extensions}/DependencyInjection/PollyServiceCollectionExtensions.cs (99%) rename src/{Polly.Hosting/Polly.Hosting.csproj => Polly.Extensions/Polly.Extensions.csproj} (85%) rename src/{Polly.Hosting => Polly.Extensions}/README.md (100%) diff --git a/build.cake b/build.cake index 45f13fb2958..782e21537bb 100644 --- a/build.cake +++ b/build.cake @@ -265,6 +265,9 @@ Task("__CreateSignedNuGetPackages") Information("Building Polly.{0}.nupkg", nugetVersion); DotNetPack(System.IO.Path.Combine(srcDir, "Polly", "Polly.csproj"), dotNetPackSettings); + + Information("Building Polly.Extensions.{0}.nupkg", nugetVersion); + DotNetPack(System.IO.Path.Combine(srcDir, "Polly.Extensions", "Polly.Extensions.csproj"), dotNetPackSettings); }); ////////////////////////////////////////////////////////////////////// diff --git a/src/Polly.Hosting.Tests/PollyDependencyInjectionKeysTests.cs b/src/Polly.Extensions.Tests/DependencyInjection/PollyDependencyInjectionKeysTests.cs similarity index 69% rename from src/Polly.Hosting.Tests/PollyDependencyInjectionKeysTests.cs rename to src/Polly.Extensions.Tests/DependencyInjection/PollyDependencyInjectionKeysTests.cs index f0faa5a9404..a85028dfcfc 100644 --- a/src/Polly.Hosting.Tests/PollyDependencyInjectionKeysTests.cs +++ b/src/Polly.Extensions.Tests/DependencyInjection/PollyDependencyInjectionKeysTests.cs @@ -1,6 +1,6 @@ -using Polly.DependencyInjection; +using Polly.Extensions.DependencyInjection; -namespace Polly.Hosting.Tests; +namespace Polly.Extensions.Tests.DependencyInjection; public class PollyDependencyInjectionKeysTests { diff --git a/src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs b/src/Polly.Extensions.Tests/DependencyInjection/PollyServiceCollectionExtensionTests.cs similarity index 95% rename from src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs rename to src/Polly.Extensions.Tests/DependencyInjection/PollyServiceCollectionExtensionTests.cs index efa0fd188a4..ddb785911d5 100644 --- a/src/Polly.Hosting.Tests/PollyServiceCollectionExtensionTests.cs +++ b/src/Polly.Extensions.Tests/DependencyInjection/PollyServiceCollectionExtensionTests.cs @@ -2,11 +2,11 @@ using Microsoft.Extensions.DependencyInjection; using Moq; using Polly.Builder; -using Polly.DependencyInjection; +using Polly.Extensions.DependencyInjection; using Polly.Registry; using Polly.Telemetry; -namespace Polly.Hosting.Tests; +namespace Polly.Extensions.Tests.DependencyInjection; public class PollyServiceCollectionExtensionTests { @@ -53,7 +53,7 @@ public void AddResilienceStrategy_MultipleRegistries_Ok() [Fact] public void AddResilienceStrategy_EnsureContextFilled() { - bool asserted = false; + var asserted = false; _services.AddResilienceStrategy(Key, context => { @@ -127,8 +127,8 @@ public void AddResilienceStrategy_Single_Ok() [Fact] public void AddResilienceStrategy_Twice_LastOneWins() { - bool firstCalled = false; - bool secondCalled = false; + var firstCalled = false; + var secondCalled = false; AddResilienceStrategy(Key, _ => firstCalled = true); AddResilienceStrategy(Key, _ => secondCalled = true); @@ -142,7 +142,7 @@ public void AddResilienceStrategy_Twice_LastOneWins() [Fact] public void AddResilienceStrategy_Multiple_Ok() { - for (int i = 0; i < 10; i++) + for (var i = 0; i < 10; i++) { AddResilienceStrategy(i.ToString(CultureInfo.InvariantCulture)); } @@ -161,7 +161,7 @@ public void AddResilienceStrategy_CustomTelemetryFactory_EnsureUsed() var asserted = false; - _services.AddSingleton(factory.Object); + _services.AddSingleton(factory.Object); _services.AddResilienceStrategy( Key, context => diff --git a/src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj b/src/Polly.Extensions.Tests/Polly.Extensions.Tests.csproj similarity index 83% rename from src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj rename to src/Polly.Extensions.Tests/Polly.Extensions.Tests.csproj index cbafa2cf790..2611628c5ef 100644 --- a/src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj +++ b/src/Polly.Extensions.Tests/Polly.Extensions.Tests.csproj @@ -8,13 +8,13 @@ true 100 $(NoWarn);SA1600;SA1204 - [Polly.Hosting]* + [Polly.Extensions]* - + diff --git a/src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs b/src/Polly.Extensions/DependencyInjection/AddResilienceStrategyContext.cs similarity index 95% rename from src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs rename to src/Polly.Extensions/DependencyInjection/AddResilienceStrategyContext.cs index af75f17db58..4f75fef7fa9 100644 --- a/src/Polly.Hosting/DependencyInjection/AddResilienceStrategyContext.cs +++ b/src/Polly.Extensions/DependencyInjection/AddResilienceStrategyContext.cs @@ -1,6 +1,6 @@ using Polly.Builder; -namespace Polly.DependencyInjection; +namespace Polly.Extensions.DependencyInjection; /// /// Represents the context for adding a resilience strategy with the specified key. diff --git a/src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs b/src/Polly.Extensions/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs similarity index 83% rename from src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs rename to src/Polly.Extensions/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs index 3e75fe8fb21..d5d143f1493 100644 --- a/src/Polly.Hosting/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs +++ b/src/Polly.Extensions/DependencyInjection/ConfigureResilienceStrategyRegistryOptions.cs @@ -1,4 +1,4 @@ -namespace Polly.DependencyInjection; +namespace Polly.Extensions.DependencyInjection; internal sealed class ConfigureResilienceStrategyRegistryOptions where TKey : notnull diff --git a/src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs b/src/Polly.Extensions/DependencyInjection/PollyDependencyInjectionKeys.cs similarity index 90% rename from src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs rename to src/Polly.Extensions/DependencyInjection/PollyDependencyInjectionKeys.cs index 69cfb201c1a..ac81a61f614 100644 --- a/src/Polly.Hosting/DependencyInjection/PollyDependencyInjectionKeys.cs +++ b/src/Polly.Extensions/DependencyInjection/PollyDependencyInjectionKeys.cs @@ -1,4 +1,4 @@ -namespace Polly.DependencyInjection; +namespace Polly.Extensions.DependencyInjection; /// /// The resilience keys used in the dependency injection scenarios. diff --git a/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs b/src/Polly.Extensions/DependencyInjection/PollyServiceCollectionExtensions.cs similarity index 99% rename from src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs rename to src/Polly.Extensions/DependencyInjection/PollyServiceCollectionExtensions.cs index e692229b12d..295b68cf843 100644 --- a/src/Polly.Hosting/DependencyInjection/PollyServiceCollectionExtensions.cs +++ b/src/Polly.Extensions/DependencyInjection/PollyServiceCollectionExtensions.cs @@ -6,7 +6,7 @@ using Polly.Telemetry; using Polly.Utils; -namespace Polly.DependencyInjection; +namespace Polly.Extensions.DependencyInjection; /// /// Provides extension methods for registering resilience strategies using the . diff --git a/src/Polly.Hosting/Polly.Hosting.csproj b/src/Polly.Extensions/Polly.Extensions.csproj similarity index 85% rename from src/Polly.Hosting/Polly.Hosting.csproj rename to src/Polly.Extensions/Polly.Extensions.csproj index a44d658479d..b501fcc02ae 100644 --- a/src/Polly.Hosting/Polly.Hosting.csproj +++ b/src/Polly.Extensions/Polly.Extensions.csproj @@ -1,8 +1,8 @@  net7.0;net6.0;netstandard2.0;net472;net462 - Polly.Hosting - Polly + Polly.Extensions + Polly.Extensions enable true Library @@ -16,7 +16,7 @@ - + diff --git a/src/Polly.Hosting/README.md b/src/Polly.Extensions/README.md similarity index 100% rename from src/Polly.Hosting/README.md rename to src/Polly.Extensions/README.md diff --git a/src/Polly.sln b/src/Polly.sln index e9f4c21bd1a..9508b82d578 100644 --- a/src/Polly.sln +++ b/src/Polly.sln @@ -39,9 +39,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "eng", "eng", "{04E3C7C5-31F EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Core.Benchmarks", "Polly.Core.Benchmarks\Polly.Core.Benchmarks.csproj", "{CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Hosting", "Polly.Hosting\Polly.Hosting.csproj", "{F2FDE6BF-DA86-4DDE-A55C-E2A064CD30D8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Extensions", "Polly.Extensions\Polly.Extensions.csproj", "{F2FDE6BF-DA86-4DDE-A55C-E2A064CD30D8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Hosting.Tests", "Polly.Hosting.Tests\Polly.Hosting.Tests.csproj", "{BB2843CA-B518-48A1-BAD9-B63238F21608}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Extensions.Tests", "Polly.Extensions.Tests\Polly.Extensions.Tests.csproj", "{BB2843CA-B518-48A1-BAD9-B63238F21608}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 0eea53543f031d8ab4845455f6820af171ae5883 Mon Sep 17 00:00:00 2001 From: martintmk Date: Thu, 30 Mar 2023 08:53:46 +0200 Subject: [PATCH 11/12] Fixes --- build.cake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.cake b/build.cake index 782e21537bb..e3345dd6288 100644 --- a/build.cake +++ b/build.cake @@ -216,7 +216,7 @@ Task("__RunMutationTests") .Does(() => { TestProject(File("./src/Polly.Core/Polly.Core.csproj"), File("./src/Polly.Core.Tests/Polly.Core.Tests.csproj"), "Polly.Core.csproj"); - TestProject(File("./src/Polly.Hosting/Polly.Hosting.csproj"), File("./src/Polly.Hosting.Tests/Polly.Hosting.Tests.csproj"), "Polly.Hosting.csproj"); + TestProject(File("./src/Polly.Extensions/Polly.Extensions.csproj"), File("./src/Polly.Extensions.Tests/Polly.Extensions.Tests.csproj"), "Polly.Extensions.csproj"); TestProject(File("./src/Polly/Polly.csproj"), File("./src/Polly.Specs/Polly.Specs.csproj"), "Polly.csproj"); void TestProject(FilePath proj, FilePath testProj, string project) From 1f95bd9f50b2ab03c66cf00610ac88eb8c32a6da Mon Sep 17 00:00:00 2001 From: martintmk Date: Thu, 30 Mar 2023 10:21:52 +0200 Subject: [PATCH 12/12] typo --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index cc855d14637..750a03c4571 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -18,7 +18,7 @@ updates: # Ignore the libraries which are pinned - dependency-name: "System.ComponentModel.Annotations" - dependency-name: "System.Threading.Tasks.Extensions" - - dependency-name: "System.ValueTuplens" + - dependency-name: "System.ValueTuple" - dependency-name: "Microsoft.Extensions.Options" - dependency-name: "Microsoft.Extensions.Logging.Abstractions" - dependency-name: "System.Diagnostics.DiagnosticSource"