diff --git a/Directory.Build.props b/Directory.Build.props index 306ea2a6..85ecdc12 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,8 +1,8 @@ - 2.23.1 - 2.23.0 + 2.24.0 + 2.23.1 12.0 enable enable diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 370e040e..cf2d30e5 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,5 +1,10 @@ # Release Notes +## 2.24.0 + +* Add `HttpClientServiceSettings.Clone`. +* Support collection syntax with MessagePack properties. + ## 2.23.1 * Throw `ArgumentNullException` instead of `NullReferenceException` when using `ServiceDelegators.Validate` with a null request. diff --git a/src/Facility.Core/Http/HttpClientServiceSettings.cs b/src/Facility.Core/Http/HttpClientServiceSettings.cs index 7b61d203..ca00298a 100644 --- a/src/Facility.Core/Http/HttpClientServiceSettings.cs +++ b/src/Facility.Core/Http/HttpClientServiceSettings.cs @@ -55,4 +55,21 @@ public sealed class HttpClientServiceSettings /// True to prevent the validation of response DTOs after receiving. /// public bool SkipResponseValidation { get; set; } + + /// + /// Creates a deep clone of the instance. + /// + public HttpClientServiceSettings Clone() => new() + { + BaseUri = BaseUri, + HttpClient = HttpClient, + ContentSerializer = ContentSerializer, + BytesSerializer = BytesSerializer, + TextSerializer = TextSerializer, + DisableChunkedTransfer = DisableChunkedTransfer, + Aspects = Aspects?.ToList(), + Synchronous = Synchronous, + SkipRequestValidation = SkipRequestValidation, + SkipResponseValidation = SkipResponseValidation, + }; } diff --git a/tests/Facility.Core.UnitTests/Http/HttpClientServiceSettingsTests.cs b/tests/Facility.Core.UnitTests/Http/HttpClientServiceSettingsTests.cs new file mode 100644 index 00000000..b3cf3e67 --- /dev/null +++ b/tests/Facility.Core.UnitTests/Http/HttpClientServiceSettingsTests.cs @@ -0,0 +1,44 @@ +using System.Collections; +using Facility.Core.Http; +using FluentAssertions; +using NUnit.Framework; + +namespace Facility.Core.UnitTests.Http; + +public class HttpClientServiceSettingsTests +{ + [Test] + public async Task CloneSettings() + { + var original = new HttpClientServiceSettings + { + BaseUri = new Uri("https://example.com"), + HttpClient = new HttpClient(), + ContentSerializer = HttpContentSerializer.Create(SystemTextJsonServiceSerializer.Instance), + BytesSerializer = BytesHttpContentSerializer.Instance, + TextSerializer = TextHttpContentSerializer.Instance, + DisableChunkedTransfer = true, + Aspects = Array.Empty(), + Synchronous = true, + SkipRequestValidation = true, + SkipResponseValidation = true, + }; + + var clone = original.Clone(); + + foreach (var property in typeof(HttpClientServiceSettings).GetProperties()) + { + var propertyType = property.PropertyType; + + var originalValue = property.GetValue(original); + var nullOrDefault = propertyType.IsValueType && Nullable.GetUnderlyingType(propertyType) is null ? Activator.CreateInstance(propertyType) : null; + originalValue.Should().NotBe(nullOrDefault, $"original {property.Name} should not be null/default."); + + var clonedValue = property.GetValue(clone); + if (clonedValue is IEnumerable and not string) + clonedValue.Should().BeEquivalentTo(originalValue, $"cloned {property.Name} should be equivalent to original."); + else + clonedValue.Should().Be(originalValue, $"cloned {property.Name} should be equal to original."); + } + } +}