From e605051df94e58acebee7f9a0eaba4f335566a03 Mon Sep 17 00:00:00 2001 From: Matthias Gernand <mgernand@users.noreply.github.com> Date: Sun, 26 May 2024 14:36:37 +0200 Subject: [PATCH] Removed dependencies. (#52) --- .../EntityTypeBuilderExtensions.cs | 3 +- ...era.ValueObject.EntityFrameworkCore.csproj | 6 +- .../CompositeContractResolver.cs | 3 +- .../Fluxera.ValueObject.JsonNet.csproj | 2 +- .../JsonSerializerSettingsExtensions.cs | 2 + .../BsonMapperExtensions.cs | 3 +- .../Fluxera.ValueObject.LiteDB.csproj | 2 +- .../ConventionPackExtensions.cs | 2 + .../Fluxera.ValueObject.MongoDB.csproj | 2 +- .../JsonSerializerOptionsExtensions.cs | 2 + .../Fluxera.ValueObject.csproj | 12 +- src/Fluxera.ValueObject/Guard.cs | 122 ++++++++++++++++++ .../PrimitiveValueObject.cs | 4 +- .../PrimitiveValueObjectConverter.cs | 3 +- src/Fluxera.ValueObject/PropertyAccessor.cs | 5 +- src/Fluxera.ValueObject/TypeExtensions.cs | 56 ++++++++ 16 files changed, 206 insertions(+), 23 deletions(-) create mode 100644 src/Fluxera.ValueObject/Guard.cs create mode 100644 src/Fluxera.ValueObject/TypeExtensions.cs diff --git a/src/Fluxera.ValueObject.EntityFrameworkCore/EntityTypeBuilderExtensions.cs b/src/Fluxera.ValueObject.EntityFrameworkCore/EntityTypeBuilderExtensions.cs index 88ea7f4..49679ca 100644 --- a/src/Fluxera.ValueObject.EntityFrameworkCore/EntityTypeBuilderExtensions.cs +++ b/src/Fluxera.ValueObject.EntityFrameworkCore/EntityTypeBuilderExtensions.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; - using Fluxera.Guards; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -23,7 +22,7 @@ public static class EntityTypeBuilderExtensions /// <param name="entityTypeBuilder"></param> public static void UsePrimitiveValueObject(this EntityTypeBuilder entityTypeBuilder) { - Guard.Against.Null(entityTypeBuilder); + Guard.ThrowIfNull(entityTypeBuilder); IEnumerable<PropertyInfo> properties = entityTypeBuilder.Metadata .ClrType diff --git a/src/Fluxera.ValueObject.EntityFrameworkCore/Fluxera.ValueObject.EntityFrameworkCore.csproj b/src/Fluxera.ValueObject.EntityFrameworkCore/Fluxera.ValueObject.EntityFrameworkCore.csproj index a70bf61..a08ad77 100644 --- a/src/Fluxera.ValueObject.EntityFrameworkCore/Fluxera.ValueObject.EntityFrameworkCore.csproj +++ b/src/Fluxera.ValueObject.EntityFrameworkCore/Fluxera.ValueObject.EntityFrameworkCore.csproj @@ -30,15 +30,15 @@ </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'net6.0'"> - <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.*" /> + <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.30" /> </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'net7.0'"> - <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.*" /> + <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.19" /> </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'net8.0'"> - <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.*" /> + <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.5" /> </ItemGroup> <ItemGroup> diff --git a/src/Fluxera.ValueObject.JsonNet/CompositeContractResolver.cs b/src/Fluxera.ValueObject.JsonNet/CompositeContractResolver.cs index d8aaa9b..8ed4507 100644 --- a/src/Fluxera.ValueObject.JsonNet/CompositeContractResolver.cs +++ b/src/Fluxera.ValueObject.JsonNet/CompositeContractResolver.cs @@ -4,7 +4,6 @@ using System.Collections; using System.Collections.Generic; using System.Linq; - using Fluxera.Guards; using JetBrains.Annotations; using Newtonsoft.Json.Serialization; @@ -42,7 +41,7 @@ IEnumerator IEnumerable.GetEnumerator() /// <param name="contractResolver"></param> public void Add(IContractResolver contractResolver) { - Guard.Against.Null(contractResolver); + Guard.ThrowIfNull(contractResolver); if(this.contractResolvers.Contains(this.defaultContractResolver)) { diff --git a/src/Fluxera.ValueObject.JsonNet/Fluxera.ValueObject.JsonNet.csproj b/src/Fluxera.ValueObject.JsonNet/Fluxera.ValueObject.JsonNet.csproj index 40967ab..dd42e1d 100644 --- a/src/Fluxera.ValueObject.JsonNet/Fluxera.ValueObject.JsonNet.csproj +++ b/src/Fluxera.ValueObject.JsonNet/Fluxera.ValueObject.JsonNet.csproj @@ -27,7 +27,7 @@ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="All" /> - <PackageReference Include="Newtonsoft.Json" Version="13.0.*" /> + <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> </ItemGroup> <ItemGroup> diff --git a/src/Fluxera.ValueObject.JsonNet/JsonSerializerSettingsExtensions.cs b/src/Fluxera.ValueObject.JsonNet/JsonSerializerSettingsExtensions.cs index 3250680..660d377 100644 --- a/src/Fluxera.ValueObject.JsonNet/JsonSerializerSettingsExtensions.cs +++ b/src/Fluxera.ValueObject.JsonNet/JsonSerializerSettingsExtensions.cs @@ -13,6 +13,8 @@ public static class JsonSerializerSettingsExtensions /// <param name="settings"></param> public static void UsePrimitiveValueObject(this JsonSerializerSettings settings) { + Guard.ThrowIfNull(settings); + settings.ContractResolver = new CompositeContractResolver { new PrimitiveValueObjectContractResolver() diff --git a/src/Fluxera.ValueObject.LiteDB/BsonMapperExtensions.cs b/src/Fluxera.ValueObject.LiteDB/BsonMapperExtensions.cs index 5d8bf62..f4d03c9 100644 --- a/src/Fluxera.ValueObject.LiteDB/BsonMapperExtensions.cs +++ b/src/Fluxera.ValueObject.LiteDB/BsonMapperExtensions.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Linq; - using Fluxera.Guards; using global::LiteDB; using JetBrains.Annotations; @@ -20,7 +19,7 @@ public static class BsonMapperExtensions /// <returns></returns> public static BsonMapper UsePrimitiveValueObject(this BsonMapper mapper) { - Guard.Against.Null(mapper); + Guard.ThrowIfNull(mapper); IEnumerable<Type> primitiveValueObjectTypes = AppDomain.CurrentDomain .GetAssemblies() diff --git a/src/Fluxera.ValueObject.LiteDB/Fluxera.ValueObject.LiteDB.csproj b/src/Fluxera.ValueObject.LiteDB/Fluxera.ValueObject.LiteDB.csproj index 1e8d149..8ed4d99 100644 --- a/src/Fluxera.ValueObject.LiteDB/Fluxera.ValueObject.LiteDB.csproj +++ b/src/Fluxera.ValueObject.LiteDB/Fluxera.ValueObject.LiteDB.csproj @@ -27,7 +27,7 @@ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="All" /> - <PackageReference Include="LiteDB" Version="5.0.*" /> + <PackageReference Include="LiteDB" Version="5.0.19" /> </ItemGroup> <ItemGroup> diff --git a/src/Fluxera.ValueObject.MongoDB/ConventionPackExtensions.cs b/src/Fluxera.ValueObject.MongoDB/ConventionPackExtensions.cs index 77257bc..04d757e 100644 --- a/src/Fluxera.ValueObject.MongoDB/ConventionPackExtensions.cs +++ b/src/Fluxera.ValueObject.MongoDB/ConventionPackExtensions.cs @@ -16,6 +16,8 @@ public static class ConventionPackExtensions /// <returns></returns> public static ConventionPack UsePrimitiveValueObject(this ConventionPack pack) { + Guard.ThrowIfNull(pack); + pack.Add(new PrimitiveValueObjectConvention()); return pack; diff --git a/src/Fluxera.ValueObject.MongoDB/Fluxera.ValueObject.MongoDB.csproj b/src/Fluxera.ValueObject.MongoDB/Fluxera.ValueObject.MongoDB.csproj index c176e14..d22d71b 100644 --- a/src/Fluxera.ValueObject.MongoDB/Fluxera.ValueObject.MongoDB.csproj +++ b/src/Fluxera.ValueObject.MongoDB/Fluxera.ValueObject.MongoDB.csproj @@ -27,7 +27,7 @@ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="All" /> - <PackageReference Include="MongoDB.Driver" Version="2.25.*" /> + <PackageReference Include="MongoDB.Driver" Version="2.25.0" /> </ItemGroup> <ItemGroup> diff --git a/src/Fluxera.ValueObject.SystemTextJson/JsonSerializerOptionsExtensions.cs b/src/Fluxera.ValueObject.SystemTextJson/JsonSerializerOptionsExtensions.cs index 5e53040..5d0a925 100644 --- a/src/Fluxera.ValueObject.SystemTextJson/JsonSerializerOptionsExtensions.cs +++ b/src/Fluxera.ValueObject.SystemTextJson/JsonSerializerOptionsExtensions.cs @@ -15,6 +15,8 @@ public static class JsonSerializerOptionsExtensions /// <param name="options"></param> public static void UsePrimitiveValueObject(this JsonSerializerOptions options) { + Guard.ThrowIfNull(options); + options.Converters.Add(new PrimitiveValueObjectJsonConverterFactory()); } } diff --git a/src/Fluxera.ValueObject/Fluxera.ValueObject.csproj b/src/Fluxera.ValueObject/Fluxera.ValueObject.csproj index c066861..27cb483 100644 --- a/src/Fluxera.ValueObject/Fluxera.ValueObject.csproj +++ b/src/Fluxera.ValueObject/Fluxera.ValueObject.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks> @@ -22,8 +22,14 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="Fluxera.Guards" Version="8.0.*" /> - <PackageReference Include="Fluxera.Utilities" Version="8.0.*" /> + <InternalsVisibleTo Include="Fluxera.ValueObject.EntityFrameworkCore" /> + <InternalsVisibleTo Include="Fluxera.ValueObject.JsonNet" /> + <InternalsVisibleTo Include="Fluxera.ValueObject.LiteDB" /> + <InternalsVisibleTo Include="Fluxera.ValueObject.MongoDB" /> + <InternalsVisibleTo Include="Fluxera.ValueObject.SystemTextJson" /> + </ItemGroup> + + <ItemGroup> <PackageReference Include="GitVersion.MsBuild" Version="5.12.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> diff --git a/src/Fluxera.ValueObject/Guard.cs b/src/Fluxera.ValueObject/Guard.cs new file mode 100644 index 0000000..e132e39 --- /dev/null +++ b/src/Fluxera.ValueObject/Guard.cs @@ -0,0 +1,122 @@ +namespace Fluxera.ValueObject +{ + using JetBrains.Annotations; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Numerics; + using System.Runtime.CompilerServices; + + internal static class Guard + { + public static T ThrowIfNull<T>(T argument, [InvokerParameterName] [CallerArgumentExpression(nameof(argument))] string parameterName = null) + { + ArgumentNullException.ThrowIfNull(argument, parameterName); + + return argument; + } + + public static string ThrowIfNullOrEmpty(string argument, [InvokerParameterName][CallerArgumentExpression(nameof(argument))] string parameterName = null) + { + argument = ThrowIfNull(argument, parameterName); + + if(string.IsNullOrEmpty(argument)) + { + throw new ArgumentException("Value cannot be empty.", parameterName); + } + + return argument; + } + + public static string ThrowIfNullOrWhiteSpace(string argument, [InvokerParameterName][CallerArgumentExpression("argument")] string parameterName = null) + { + argument = ThrowIfNull(argument, parameterName); + + if(string.IsNullOrWhiteSpace(argument)) + { + throw new ArgumentException("Value cannot be whitespace-only.", parameterName); + } + + return argument; + } + + public static bool ThrowIfFalse(bool argument, [InvokerParameterName][CallerArgumentExpression(nameof(argument))] string parameterName = null, string message = null) + { + if(!argument) + { + throw new ArgumentException(message ?? "Value cannot be false.", parameterName); + } + + return true; + } + + public static IEnumerable<T> ThrowIfNullOrEmpty<T>(IEnumerable<T> argument, [InvokerParameterName][CallerArgumentExpression(nameof(argument))] string parameterName = null) + { + argument = ThrowIfNull(argument, parameterName); + + // ReSharper disable PossibleMultipleEnumeration + if(!argument.Any()) + { + throw new ArgumentException("Enumerable cannot be empty.", parameterName); + } + + return argument; + // ReSharper enable PossibleMultipleEnumeration + } + +#if NET7_0_OR_GREATER + public static T ThrowIfNegative<T>(T argument, [InvokerParameterName] [CallerArgumentExpression(nameof(argument))] string parameterName = null) + where T : INumber<T> + { + if(T.IsNegative(argument)) + { + throw new ArgumentException("Value cannot be negative.", parameterName); + } + + return argument; + } +#endif + +#if NET6_0 + public static byte ThrowIfNegative(byte argument, [InvokerParameterName][CallerArgumentExpression(nameof(argument))] string parameterName = null) + { + if(argument < 0) + { + throw new ArgumentException("Value cannot be negative.", parameterName); + } + + return argument; + } + + public static short ThrowIfNegative(short argument, [InvokerParameterName][CallerArgumentExpression(nameof(argument))] string parameterName = null) + { + if(argument < 0) + { + throw new ArgumentException("Value cannot be negative.", parameterName); + } + + return argument; + } + + public static int ThrowIfNegative(int argument, [InvokerParameterName] [CallerArgumentExpression(nameof(argument))] string parameterName = null) + { + if(argument < 0) + { + throw new ArgumentException("Value cannot be negative.", parameterName); + } + + return argument; + } + + public static long ThrowIfNegative(long argument, [InvokerParameterName][CallerArgumentExpression(nameof(argument))] string parameterName = null) + { + if(argument < 0) + { + throw new ArgumentException("Value cannot be negative.", parameterName); + } + + return argument; + } +#endif + } +} diff --git a/src/Fluxera.ValueObject/PrimitiveValueObject.cs b/src/Fluxera.ValueObject/PrimitiveValueObject.cs index 0234ad5..60a65e8 100644 --- a/src/Fluxera.ValueObject/PrimitiveValueObject.cs +++ b/src/Fluxera.ValueObject/PrimitiveValueObject.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; using System.ComponentModel; - using Fluxera.Guards; - using Fluxera.Utilities.Extensions; using JetBrains.Annotations; /// <summary> @@ -29,7 +27,7 @@ static PrimitiveValueObject() Type valueType = typeof(TValue); bool isPrimitive = valueType.IsPrimitive(true); - Guard.Against.False(isPrimitive, nameof(Value), "The value of a primitive value object must be a primitive, string or enum value."); + Guard.ThrowIfFalse(isPrimitive, nameof(Value), "The value of a primitive value object must be a primitive, string or enum value."); } /// <summary> diff --git a/src/Fluxera.ValueObject/PrimitiveValueObjectConverter.cs b/src/Fluxera.ValueObject/PrimitiveValueObjectConverter.cs index b02ea52..c420b1a 100644 --- a/src/Fluxera.ValueObject/PrimitiveValueObjectConverter.cs +++ b/src/Fluxera.ValueObject/PrimitiveValueObjectConverter.cs @@ -4,7 +4,6 @@ using System.Collections.Concurrent; using System.ComponentModel; using System.Globalization; - using Fluxera.Guards; internal sealed class PrimitiveValueObjectConverter : TypeConverter { @@ -106,7 +105,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c /// <inheritdoc /> public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { - Guard.Against.Null(value); + Guard.ThrowIfNull(value); PrimitiveValueObject<TValueObject, TValue> primitiveValueObject = (PrimitiveValueObject<TValueObject, TValue>)value; diff --git a/src/Fluxera.ValueObject/PropertyAccessor.cs b/src/Fluxera.ValueObject/PropertyAccessor.cs index 5a7eab2..d28aa38 100644 --- a/src/Fluxera.ValueObject/PropertyAccessor.cs +++ b/src/Fluxera.ValueObject/PropertyAccessor.cs @@ -4,7 +4,6 @@ using System.Collections.Concurrent; using System.Linq; using System.Reflection; - using Fluxera.Guards; using JetBrains.Annotations; [PublicAPI] @@ -16,8 +15,8 @@ internal sealed class PropertyAccessor private PropertyAccessor(string propertyName, Func<object, object> getterFunc) { - Guard.Against.NullOrWhiteSpace(propertyName, nameof(propertyName)); - Guard.Against.Null(getterFunc, nameof(getterFunc)); + Guard.ThrowIfNullOrWhiteSpace(propertyName); + Guard.ThrowIfNull(getterFunc); this.PropertyName = propertyName; this.GetterFunc = getterFunc; diff --git a/src/Fluxera.ValueObject/TypeExtensions.cs b/src/Fluxera.ValueObject/TypeExtensions.cs new file mode 100644 index 0000000..8ae2f10 --- /dev/null +++ b/src/Fluxera.ValueObject/TypeExtensions.cs @@ -0,0 +1,56 @@ +namespace Fluxera.ValueObject +{ + using System; + using System.Collections.Generic; + + internal static class TypeExtensions + { + private static readonly HashSet<Type> ExtraPrimitiveTypes = + [ + typeof(string), + typeof(decimal), + typeof(DateOnly), + typeof(TimeOnly), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), + typeof(Guid) + ]; + + /// <summary> + /// Determines whether the specified type is a primitive. It automatically + /// unwraps the wrapped type of the nullable. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="includeEnums">If set to <c>true</c> include enums.</param> + /// <returns> + /// <c>true</c> if the specified type is a primitive; otherwise, <c>false</c>. + /// </returns> + public static bool IsPrimitive(this Type type, bool includeEnums = false) + { + type = type.UnwrapNullableType(); + + if(type.IsPrimitive) + { + return true; + } + + if(includeEnums && type.IsEnum) + { + return true; + } + + return ExtraPrimitiveTypes.Contains(type); + } + + /// <summary> + /// Gets the type without nullable if the type is a <see cref="Nullable{T}" />. + /// </summary> + /// <param name="type">The type.</param> + /// <returns></returns> + private static Type UnwrapNullableType(this Type type) + { + return Nullable.GetUnderlyingType(type) ?? type; + } + } +}