Skip to content

Commit 87adc5e

Browse files
Next (#162)
* Fixes #159, Only supports netstandard2.0 and netstandard2.1 * Fixes #161 * Changes EnsureOptions to be readonly * Change so that Ensure.That returns the Param * NuGet upgrades * Fixes benchmark * Docs
1 parent 0273546 commit 87adc5e

36 files changed

+1000
-459
lines changed

README.md

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,88 @@
11
# Ensure.That
22
Ensure.That is a simple guard clause argument validation lib, that helps you with validation of your arguments.
33

4-
It's developed for .NET 4.5.1 as well as .NET Standard 1.1, 2.0, and 2.1 available via [NuGet](https://www.nuget.org/packages/ensure.that/).
4+
It's developed for .NET Standard 2.0 and 2.1 available via [NuGet](https://www.nuget.org/packages/ensure.that/).
55

66
[![Build Status](https://dev.azure.com/daniel-wertheim/os/_apis/build/status/Ensure.That-CI?branchName=master)](https://dev.azure.com/daniel-wertheim/os/_build/latest?definitionId=1&branchName=master)
77
[![NuGet](https://img.shields.io/nuget/v/ensure.that.svg)](http://nuget.org/packages/ensure.that)
88

99
## Using extension methods
10-
This was supposed to be removed but after some wishes from the community it has been kept it with some slight changes.
11-
12-
If you are worried that the constructed `public struct Param<T> {}` created for the argument being validated will hurt your performance you can use any of the other constructs e.g. contextual `Ensure.String` or `EnsureArg`.
1310

1411
```csharp
1512
Ensure.That(myString).IsNotNullOrWhiteSpace();
1613
Ensure.That(myString, nameof(myArg)).IsNotNullOrWhiteSpace();
17-
Ensure.That(myString, nameof(myArg), opts => opts.WithMessage("Foo")).IsNotNullOrWhiteSpace();
14+
Ensure.That(myString, nameof(myArg), (in EnsureOptions opts) => opts.WithMessage("Foo")).IsNotNullOrWhiteSpace();
15+
```
16+
17+
Chainable:
18+
19+
```csharp
20+
Ensure
21+
.That(myString)
22+
.IsNotNullOrWhiteSpace()
23+
.IsGuid();
1824
```
1925

26+
Easily extendable:
27+
28+
```csharp
29+
public static class StringArgExtensions
30+
{
31+
public static StringParam IsNotFishy(this StringParam param)
32+
=> param.Value != "fishy"
33+
? param
34+
: throw Ensure.ExceptionFactory.ArgumentException("Something is fishy!", param.Name);
35+
}
36+
37+
Ensure.That(myString, nameof(myString)).IsNotFishy();
38+
```
39+
40+
**NOTE:** If you are worried that the constructed `public readonly struct Param<T> {}` created for the argument being validated will hurt your performance you can use any of the other constructs e.g. contextual `Ensure.String` or `EnsureArg` (see below for samples).
41+
2042
## Using contextual validation
21-
This flavour was introduced in the `v7.0.0` release.
43+
Introduced in the `v7.0.0` release.
2244

2345
```csharp
2446
Ensure.String.IsNotNullOrWhiteSpace(myString);
2547
Ensure.String.IsNotNullOrWhiteSpace(myString, nameof(myArg));
26-
Ensure.String.IsNotNullOrWhiteSpace(myString, nameof(myArg), opts => opts.WithMessage("Foo"));
48+
Ensure.String.IsNotNullOrWhiteSpace(myString, nameof(myArg), (in EnsureOptions opts) => opts.WithMessage("Foo"));
2749
```
50+
51+
Easily extendable:
52+
53+
```csharp
54+
public static class StringArgExtensions
55+
{
56+
public static string IsNotFishy(this StringArg _, string value, string paramName = null)
57+
=> value != "fishy"
58+
? value
59+
: throw Ensure.ExceptionFactory.ArgumentException("Something is fishy!", paramName);
60+
}
61+
62+
Ensure.String.IsNotFishy(myString, nameof(myString));
63+
```
64+
2865
### Using static simple methods
29-
The `EnsureArg` flavour was added in the `v5.0.0` release.
66+
Introduced in the `v5.0.0` release.
3067

3168
```csharp
3269
EnsureArg.IsNotNullOrWhiteSpace(myString);
3370
EnsureArg.IsNotNullOrWhiteSpace(myString, nameof(myArg));
34-
EnsureArg.IsNotNullOrWhiteSpace(myString, nameof(myArg), opts => opts.WithMessage("Foo"));
71+
EnsureArg.IsNotNullOrWhiteSpace(myString, nameof(myArg), (in EnsureOptions opts) => opts.WithMessage("Foo"));
72+
```
73+
74+
Easily extendable:
75+
76+
```csharp
77+
public static partial class EnsureArg
78+
{
79+
public static string IsNotFishy(string value, string paramName = null)
80+
=> value != "fishy"
81+
? value
82+
: throw Ensure.ExceptionFactory.ArgumentException("Something is fishy!", paramName);
83+
}
84+
85+
EnsureArg.IsNotFishy(myString, nameof(myString));
3586
```
3687

3788
## Samples
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ name: $(SemVer)
22

33
variables:
44
BuildConfiguration: Release
5-
BuildRev: $[counter(format('{0:yyyyMMdd}', pipeline.startTime), 1)]
65
SemVer: $[ variables['Build.SourceBranchName'] ]
76
CommitId: $(Build.SourceVersion)
87

@@ -15,8 +14,8 @@ trigger:
1514
pr: none
1615

1716
pool:
18-
vmImage: windows-2019
17+
vmImage: ubuntu-latest
1918

2019
stages:
21-
- template: azure-templates/stage-build.yml
22-
- template: azure-templates/stage-deploy.yml
20+
- template: stage-build.yml
21+
- template: stage-deploy.yml
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pr:
1919
- master
2020

2121
pool:
22-
vmImage: windows-2019
22+
vmImage: ubuntu-latest
2323

2424
stages:
25-
- template: azure-templates/stage-build.yml
25+
- template: stage-build.yml
Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,32 @@ stages:
1313
projects: 'src/*.sln'
1414
arguments: '-c $(BuildConfiguration) --no-incremental --nologo -p:TreatWarningsAsErrors=true -p:Version=$(SemVer) -p:InformationalVersion=$(CommitId)'
1515

16-
- task: DotNetCoreCLI@2
17-
displayName: 'UnitTests .Net4.5.2'
18-
inputs:
19-
command: test
20-
projects: 'src/Tests/**/UnitTests.csproj'
21-
arguments: '-c $(BuildConfiguration) -f net452 --no-build'
22-
testRunTitle: 'UnitTests .Net4.5.2'
23-
2416
- task: DotNetCoreCLI@2
2517
displayName: 'UnitTests .NetCoreApp3.1'
2618
inputs:
2719
command: test
28-
projects: 'src/Tests/**/UnitTests.csproj'
20+
projects: 'src/**/UnitTests.csproj'
2921
arguments: '-c $(BuildConfiguration) -f netcoreapp3.1 --no-build'
3022
testRunTitle: 'UnitTests .NetCoreApp3.1'
3123

3224
- task: DotNetCoreCLI@2
3325
displayName: 'UnitTests .Net5'
3426
inputs:
3527
command: test
36-
projects: 'src/Tests/**/UnitTests.csproj'
28+
projects: 'src/**/UnitTests.csproj'
3729
arguments: '-c $(BuildConfiguration) -f net5.0 --no-build'
3830
testRunTitle: 'UnitTests .Net5'
39-
31+
4032
- task: DotNetCoreCLI@2
4133
displayName: 'Pack Nupkg'
4234
inputs:
4335
command: custom
4436
custom: pack
4537
projects: 'src/*.sln'
4638
arguments: '-c $(BuildConfiguration) --no-build -o $(Build.ArtifactStagingDirectory) -p:Version=$(SemVer) -p:InformationalVersion=$(CommitId)'
47-
39+
4840
- task: PublishPipelineArtifact@1
4941
displayName: 'Publish Artifacts'
5042
inputs:
5143
path: '$(Build.ArtifactStagingDirectory)'
52-
artifact: Artifacts
44+
artifact: Artifacts

src/projects/EnsureThat/Annotations/JetBrains.cs

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
SOFTWARE. */
2222

2323
using System;
24+
using System.Diagnostics.CodeAnalysis;
2425

2526
#pragma warning disable 1591
2627
// ReSharper disable UnusedMember.Global
@@ -44,40 +45,6 @@ internal sealed class RegexPatternAttribute : Attribute { }
4445
[AttributeUsage(AttributeTargets.Parameter)]
4546
internal sealed class NoEnumerationAttribute : Attribute { }
4647

47-
/// <summary>
48-
/// Indicates that the value of the marked element could never be <c>null</c>.
49-
/// </summary>
50-
/// <example><code>
51-
/// [NotNull] object Foo() {
52-
/// return null; // Warning: Possible 'null' assignment
53-
/// }
54-
/// </code></example>
55-
[AttributeUsage(
56-
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |
57-
AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event |
58-
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)]
59-
internal sealed class NotNullAttribute : Attribute { }
60-
61-
/// <summary>
62-
/// Indicates that a method does not make any observable state changes.
63-
/// The same as <c>System.Diagnostics.Contracts.PureAttribute</c>.
64-
/// </summary>
65-
/// <example><code>
66-
/// [Pure] int Multiply(int x, int y) => x * y;
67-
///
68-
/// void M() {
69-
/// Multiply(123, 42); // Waring: Return value of pure method is not used
70-
/// }
71-
/// </code></example>
72-
/// <remarks>
73-
/// <c>System.Diagnostics.Contracts.PureAttribute</c> is not available for NETSTANDARD1_1.
74-
/// For consistency, using this version of the attribute for all profiles rather than
75-
/// just NETSTANDARD1_1.
76-
/// </remarks>
77-
[AttributeUsage(AttributeTargets.Method)]
78-
internal sealed class PureAttribute : Attribute { }
79-
80-
8148
/// <summary>
8249
/// Indicates that the function argument should be string literal and match one
8350
/// of the parameters of the caller function. For example, ReSharper annotates
@@ -129,7 +96,7 @@ internal sealed class InvokerParameterNameAttribute : Attribute { }
12996
/// // A method that returns null if the parameter is null,
13097
/// // and not null if the parameter is not null
13198
/// [ContractAnnotation("null =&gt; null; notnull =&gt; notnull")]
132-
/// public object Transform(object data)
99+
/// public object Transform(object data)
133100
/// </code></item>
134101
/// <item><code>
135102
/// [ContractAnnotation("=&gt; true, result: notnull; =&gt; false, result: null")]

src/projects/EnsureThat/Annotations/NotNullAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace System.Diagnostics.CodeAnalysis
55
{
66
/// <summary>
77
/// This is JUST so we can avoid having #if regions in each usage site.
8-
///
8+
///
99
/// For non-supported frameworks, it may be ignored by CodeAnalysis, but allows the usage
1010
/// sites to avoid all having
1111
/// <code>

src/projects/EnsureThat/Enforcers/AnyArg.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ public T HasValue<T>([NoEnumeration, ValidatedNotNull, NotNull] T value, [Invoke
3131
return value;
3232
}
3333

34+
/// <summary>
35+
/// Ensures value is not null.
36+
/// Supports both <see cref="Nullable{T}"/> and reference types.
37+
/// If you know you are dealing with a certain type, e.g struct use preferred <see cref="IsNotNull{T}(T?, string, OptsFn)"/>
38+
/// overload instead as it is more performant.
39+
/// </summary>
40+
/// <typeparam name="T"></typeparam>
41+
/// <param name="value"></param>
42+
/// <param name="paramName"></param>
43+
/// <param name="optsFn"></param>
44+
/// <returns></returns>
45+
/// <remarks>If you know you are dealing with e.g. a struct, the <see cref="IsNotNull{T}(T?, string, OptsFn)"/> overload is more performant.</remarks>
3446
[return: NotNull]
3547
[ContractAnnotation("value:null => halt")]
3648
public T IsNotNull<T>([NoEnumeration, ValidatedNotNull, NotNull] T value, [InvokerParameterName] string paramName = null, OptsFn optsFn = null) where T : class

0 commit comments

Comments
 (0)