Skip to content

Commit d60bb46

Browse files
authored
Validator and text fixes. (#94)
1 parent d6579bb commit d60bb46

33 files changed

+248
-125
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
Represents the **NuGet** versions.
44

5+
## v3.14.1
6+
- *Fixed*: The `Result.ValidatesAsync` extension method signature has had the value nullability corrected to enable fluent-style method-chaining.
7+
- *Fixed*: The fully qualified type and property name is now correctly used as the `LText.KeyAndOrText` when creating within the `PropertyExpression<TEntity, TProperty>` to enable a qualified _key_ that can be used by the `ITextProvider` to substitute the text at runtime; the existing text fallback behavior remains such that an appropriate text is used. The `PropertyExpression.CreatePropertyLTextKey` function can be overridden to change this behavior.
8+
59
## v3.14.0
610
- *Enhancement*: Planned feature obsoletion. The `TypedHttpClientBase` methods `WithRetry`, `WithTimeout`, `WithCustomRetryPolicy` and `WithMaxRetryDelay` are now marked as obsolete and will result in a compile-time warning. Related `TypedHttpClientOptions`, `HttpRequestLogger` and `SettingsBase` capabilities have also been obsoleted.
711
- Why? Primarily based on Microsoft guidance around [`IHttpClientFactory`](https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory) usage. Specifically advances in native HTTP [resilency](https://learn.microsoft.com/en-us/dotnet/core/resilience/http-resilience) support, and the [.NET 8 networking improvements](https://devblogs.microsoft.com/dotnet/dotnet-8-networking-improvements/).

Common.targets

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>3.14.0</Version>
3+
<Version>3.14.1</Version>
44
<LangVersion>preview</LangVersion>
55
<Authors>Avanade</Authors>
66
<Company>Avanade</Company>

samples/My.Hr/My.Hr.Database/My.Hr.Database.csproj

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
</ItemGroup>
2222

2323
<ItemGroup>
24-
<PackageReference Include="DbEx.SqlServer" Version="2.4.0" />
24+
<PackageReference Include="DbEx.SqlServer" Version="2.5.0" />
25+
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
2526
</ItemGroup>
2627

2728
<ItemGroup>

samples/My.Hr/My.Hr.UnitTest/My.Hr.UnitTest.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@
2020
</ItemGroup>
2121

2222
<ItemGroup>
23-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
23+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
2424
<PackageReference Include="NUnit" Version="4.1.0" />
25-
<PackageReference Include="NUnit.Analyzers" Version="4.0.1">
25+
<PackageReference Include="NUnit.Analyzers" Version="4.1.0">
2626
<PrivateAssets>all</PrivateAssets>
2727
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2828
</PackageReference>
2929
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
30-
<PackageReference Include="coverlet.collector" Version="6.0.0">
30+
<PackageReference Include="coverlet.collector" Version="6.0.2">
3131
<PrivateAssets>all</PrivateAssets>
3232
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3333
</PackageReference>

src/CoreEx.Azure/CoreEx.Azure.csproj

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17-
<PackageReference Include="Azure.Data.Tables" Version="12.8.2" />
18-
<PackageReference Include="Azure.Messaging.ServiceBus" Version="7.17.2" />
17+
<PackageReference Include="Azure.Data.Tables" Version="12.8.3" />
18+
<PackageReference Include="Azure.Messaging.ServiceBus" Version="7.17.4" />
1919
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
20-
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="5.16.0" />
20+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="5.17.0" />
2121
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.2.0" />
22-
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.ServiceBus" Version="5.13.5" />
23-
<PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="7.0.0" />
22+
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.ServiceBus" Version="5.14.0" />
23+
<PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="7.1.0" />
2424
</ItemGroup>
2525

2626
<Import Project="..\..\Common.targets" />

src/CoreEx.Cosmos/CoreEx.Cosmos.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
<Import Project="..\..\Common.targets" />
1313

1414
<ItemGroup>
15-
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.38.0" />
16-
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.8" />
15+
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.38.1" />
16+
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.10" />
1717
</ItemGroup>
1818

1919
<ItemGroup>

src/CoreEx.Database.SqlServer/CoreEx.Database.SqlServer.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<ItemGroup>
1515
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="8.0.0" />
1616
<PackageReference Include="Azure.Identity" Version="1.10.4" />
17-
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.5" />
17+
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
1818
</ItemGroup>
1919

2020
<ItemGroup>

src/CoreEx.EntityFrameworkCore/CoreEx.EntityFrameworkCore.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
<Import Project="..\..\Common.targets" />
1414

1515
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
16-
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.26" />
16+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.28" />
1717
</ItemGroup>
1818

1919
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
20-
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.15" />
20+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.17" />
2121
</ItemGroup>
2222

2323
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
24-
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
24+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
2525
</ItemGroup>
2626

2727
<ItemGroup>

src/CoreEx.UnitTesting.NUnit/CoreEx.UnitTesting.NUnit.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<Import Project="..\..\Common.targets" />
1313

1414
<ItemGroup>
15-
<PackageReference Include="UnitTestEx.NUnit" Version="4.2.0" />
15+
<PackageReference Include="UnitTestEx.NUnit" Version="4.3.0" />
1616
</ItemGroup>
1717

1818
<ItemGroup>

src/CoreEx.UnitTesting/CoreEx.UnitTesting.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
<ItemGroup>
2121
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
22-
<PackageReference Include="UnitTestEx" Version="4.2.0" />
22+
<PackageReference Include="UnitTestEx" Version="4.3.0" />
2323
</ItemGroup>
2424

2525
</Project>

src/CoreEx.Validation/IEntityRule.cs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/CoreEx
2+
3+
using System;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
namespace CoreEx.Validation
8+
{
9+
/// <summary>
10+
/// Provides a validation rule for an entity.
11+
/// </summary>
12+
/// <typeparam name="TEntity">The entity <see cref="Type"/>.</typeparam>
13+
public interface IEntityRule<TEntity> where TEntity : class
14+
{
15+
/// <summary>
16+
/// Validates an entity given a <see cref="ValidationContext{TEntity}"/>.
17+
/// </summary>
18+
/// <param name="context">The <see cref="ValidationContext{TEntity}"/></param>
19+
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
20+
Task ValidateAsync(ValidationContext<TEntity> context, CancellationToken cancellationToken);
21+
}
22+
}
+33-7
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,48 @@
11
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/CoreEx
22

3-
using System;
3+
using CoreEx.Localization;
44
using System.Threading;
55
using System.Threading.Tasks;
66

77
namespace CoreEx.Validation
88
{
99
/// <summary>
10-
/// Provides a validation rule for a property.
10+
/// Enables a validation rule for an entity property.
1111
/// </summary>
12-
/// <typeparam name="TEntity">The entity <see cref="Type"/>.</typeparam>
13-
public interface IPropertyRule<TEntity> where TEntity : class
12+
public interface IPropertyRule
1413
{
1514
/// <summary>
16-
/// Validates an entity given a <see cref="ValidationContext{TEntity}"/>.
15+
/// Gets the property name.
16+
/// </summary>
17+
public string Name { get; }
18+
19+
/// <summary>
20+
/// Gets the JSON property name.
21+
/// </summary>
22+
public string JsonName { get; }
23+
24+
/// <summary>
25+
/// Gets or sets the friendly text name used in validation messages.
26+
/// </summary>
27+
public LText Text { get; set; }
28+
29+
/// <summary>
30+
/// Executes the validation for the property value.
1731
/// </summary>
18-
/// <param name="context">The <see cref="ValidationContext{TEntity}"/></param>
1932
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
20-
Task ValidateAsync(ValidationContext<TEntity> context, CancellationToken cancellationToken);
33+
/// <returns>A <see cref="ValueValidatorResult{TEntity, TProperty}"/>.</returns>
34+
Task<IValidationResult> ValidateAsync(CancellationToken cancellationToken = default);
35+
36+
/// <summary>
37+
/// Executes the validation for the property value.
38+
/// </summary>
39+
/// <param name="throwOnError">Indicates whether to automatically throw a <see cref="ValidationException"/> where <see cref="IValidationResult.HasErrors"/>.</param>
40+
/// <param name="cancellationToken">>The <see cref="CancellationToken"/>.</param>
41+
/// <returns>A <see cref="ValueValidatorResult{TEntity, TProperty}"/>.</returns>
42+
public async Task<IValidationResult> ValidateAsync(bool throwOnError, CancellationToken cancellationToken = default)
43+
{
44+
var ir = await ValidateAsync(cancellationToken).ConfigureAwait(false);
45+
return throwOnError ? ir.ThrowOnError() : ir;
46+
}
2147
}
2248
}

src/CoreEx.Validation/IPropertyRuleT2.cs

+1-38
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/CoreEx
22

3-
using CoreEx.Localization;
43
using CoreEx.Validation.Clauses;
54
using CoreEx.Validation.Rules;
65
using System;
76
using System.Linq.Expressions;
8-
using System.Threading;
9-
using System.Threading.Tasks;
107

118
namespace CoreEx.Validation
129
{
@@ -15,23 +12,8 @@ namespace CoreEx.Validation
1512
/// </summary>
1613
/// <typeparam name="TEntity">The entity <see cref="Type"/>.</typeparam>
1714
/// <typeparam name="TProperty">The property <see cref="Type"/>.</typeparam>
18-
public interface IPropertyRule<TEntity, in TProperty> where TEntity : class
15+
public interface IPropertyRule<TEntity, in TProperty> : IPropertyRule where TEntity : class
1916
{
20-
/// <summary>
21-
/// Gets the property name.
22-
/// </summary>
23-
public string Name { get; }
24-
25-
/// <summary>
26-
/// Gets the JSON property name.
27-
/// </summary>
28-
public string JsonName { get; }
29-
30-
/// <summary>
31-
/// Gets or sets the friendly text name used in validation messages.
32-
/// </summary>
33-
public LText Text { get; set; }
34-
3517
/// <summary>
3618
/// Adds a clause (<see cref="IPropertyRuleClause{TEntity, TProperty}"/>) to the rule.
3719
/// </summary>
@@ -45,25 +27,6 @@ public interface IPropertyRule<TEntity, in TProperty> where TEntity : class
4527
/// <returns>The <see cref="PropertyRuleBase{TEntity, TProperty}"/>.</returns>
4628
IPropertyRule<TEntity, TProperty> AddRule(IValueRule<TEntity, TProperty> rule);
4729

48-
/// <summary>
49-
/// Executes the validation for the property value.
50-
/// </summary>
51-
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
52-
/// <returns>A <see cref="ValueValidatorResult{TEntity, TProperty}"/>.</returns>
53-
Task<IValidationResult> ValidateAsync(CancellationToken cancellationToken = default);
54-
55-
/// <summary>
56-
/// Executes the validation for the property value.
57-
/// </summary>
58-
/// <param name="throwOnError">Indicates whether to automatically throw a <see cref="ValidationException"/> where <see cref="IValidationResult.HasErrors"/>.</param>
59-
/// <param name="cancellationToken">>The <see cref="CancellationToken"/>.</param>
60-
/// <returns>A <see cref="ValueValidatorResult{TEntity, TProperty}"/>.</returns>
61-
public async Task<IValidationResult> ValidateAsync(bool throwOnError, CancellationToken cancellationToken = default)
62-
{
63-
var ir = await ValidateAsync(cancellationToken).ConfigureAwait(false);
64-
return throwOnError ? ir.ThrowOnError() : ir;
65-
}
66-
6730
/// <summary>
6831
/// Adds a <see cref="DependsOnClause{TEntity, TProperty}"/> to this <see cref="PropertyRule{TEntity, TProperty}"/> in that another specified property of the entity must have a non-default value (and not have a validation error) to continue.
6932
/// </summary>

src/CoreEx.Validation/IncludeBaseRule.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace CoreEx.Validation
1111
/// </summary>
1212
/// <typeparam name="TEntity">The entity <see cref="Type"/>.</typeparam>
1313
/// <typeparam name="TInclude">The entity base <see cref="Type"/>.</typeparam>
14-
public class IncludeBaseRule<TEntity, TInclude> : ValidatorBase<TEntity>, IPropertyRule<TEntity> where TEntity : class where TInclude : class
14+
public class IncludeBaseRule<TEntity, TInclude> : ValidatorBase<TEntity>, IEntityRule<TEntity> where TEntity : class where TInclude : class
1515
{
1616
private readonly IValidatorEx<TInclude> _include;
1717

src/CoreEx.Validation/PropertyRule.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace CoreEx.Validation
1515
/// </summary>
1616
/// <typeparam name="TEntity">The entity <see cref="Type"/>.</typeparam>
1717
/// <typeparam name="TProperty">The property <see cref="Type"/>.</typeparam>
18-
public class PropertyRule<TEntity, TProperty> : PropertyRuleBase<TEntity, TProperty>, IPropertyRule<TEntity>, IValueRule<TEntity, TProperty> where TEntity : class
18+
public class PropertyRule<TEntity, TProperty> : PropertyRuleBase<TEntity, TProperty>, IEntityRule<TEntity>, IValueRule<TEntity, TProperty> where TEntity : class
1919
{
2020
private readonly PropertyExpression<TEntity, TProperty> _property;
2121

src/CoreEx.Validation/PropertyRuleBase.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,6 @@ protected async Task InvokeAsync(PropertyContext<TEntity, TProperty> context, Ca
108108
public abstract Task<ValueValidatorResult<TEntity, TProperty>> ValidateAsync(CancellationToken cancellationToken = default);
109109

110110
/// <inheritdoc/>
111-
async Task<IValidationResult> IPropertyRule<TEntity, TProperty>.ValidateAsync(CancellationToken cancellationToken) => await ValidateAsync(cancellationToken).ConfigureAwait(false);
111+
async Task<IValidationResult> IPropertyRule.ValidateAsync(CancellationToken cancellationToken) => await ValidateAsync(cancellationToken).ConfigureAwait(false);
112112
}
113113
}

src/CoreEx.Validation/RuleSet.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace CoreEx.Validation
1010
/// Represents a validation rule set for an entity, in that it groups one or more <see cref="Rules"/> together for a specified condition.
1111
/// </summary>
1212
/// <typeparam name="TEntity">The entity <see cref="Type"/>.</typeparam>
13-
public class RuleSet<TEntity> : ValidatorBase<TEntity>, IPropertyRule<TEntity> where TEntity : class
13+
public class RuleSet<TEntity> : ValidatorBase<TEntity>, IEntityRule<TEntity> where TEntity : class
1414
{
1515
/// <summary>
1616
/// Initializes a new instance of the <see cref="RuleSet{TEntity}"/> class to be invoked where the predicate is true.

0 commit comments

Comments
 (0)