diff --git a/.gitignore b/.gitignore
index dfcfd56f..0bdc52e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
-## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
@@ -23,6 +23,7 @@ mono_crash.*
[Rr]eleases/
x64/
x86/
+[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
@@ -61,6 +62,9 @@ project.lock.json
project.fragment.lock.json
artifacts/
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
# StyleCop
StyleCopReport.xml
@@ -86,6 +90,7 @@ StyleCopReport.xml
*.tmp_proj
*_wpftmp.csproj
*.log
+*.tlog
*.vspscc
*.vssscc
.builds
@@ -137,6 +142,11 @@ _TeamCity*
.axoCover/*
!.axoCover/settings.json
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
# Visual Studio code coverage results
*.coverage
*.coveragexml
@@ -284,6 +294,17 @@ node_modules/
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
@@ -340,6 +361,9 @@ ASALocalRun/
# Local History for Visual Studio
.localhistory/
+# Visual Studio History (VSHistory) files
+.vshistory/
+
# BeatPulse healthcheck temp database
healthchecksdb
@@ -348,3 +372,28 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
+.idea/
\ No newline at end of file
diff --git a/src/MADE.Collections/CollectionExtensions.cs b/src/MADE.Collections/CollectionExtensions.cs
index 6bc936c7..18048c7f 100644
--- a/src/MADE.Collections/CollectionExtensions.cs
+++ b/src/MADE.Collections/CollectionExtensions.cs
@@ -12,6 +12,60 @@ namespace MADE.Collections
///
public static class CollectionExtensions
{
+ ///
+ /// Adds the specified item to the collection based on the specified condition being true.
+ ///
+ /// The collection to add the item to.
+ /// The item to add.
+ /// The condition required to add the item.
+ /// The type of item within the collection.
+ /// Thrown if the or is .
+ /// Potentially thrown by the delegate callback.
+ public static void AddIf(this IList collection, T item, Func condition)
+ {
+ if (collection == null)
+ {
+ throw new ArgumentNullException(nameof(collection));
+ }
+
+ if (condition == null)
+ {
+ throw new ArgumentNullException(nameof(condition));
+ }
+
+ if (condition())
+ {
+ collection.Add(item);
+ }
+ }
+
+ ///
+ /// Removes the specified item from the collection based on the specified condition being true.
+ ///
+ /// The collection to remove the item from.
+ /// The item to remove.
+ /// The condition required to remove the item.
+ /// The type of item within the collection.
+ /// Thrown if the or is .
+ /// Potentially thrown by the delegate callback.
+ public static void RemoveIf(this IList collection, T item, Func condition)
+ {
+ if (collection == null)
+ {
+ throw new ArgumentNullException(nameof(collection));
+ }
+
+ if (condition == null)
+ {
+ throw new ArgumentNullException(nameof(condition));
+ }
+
+ if (condition())
+ {
+ collection.Remove(item);
+ }
+ }
+
///
/// Updates an item within the collection.
///
@@ -114,6 +168,31 @@ public static void AddRange(this ICollection collection, IEnumerable it
}
}
+ ///
+ /// Adds the specified collection of items to the collection based on the specified condition being true.
+ ///
+ /// The collection to add the items to.
+ /// The items to add.
+ /// The condition required to add the items.
+ /// The type of item within the collection.
+ /// Thrown if the , or is .
+ /// Potentially thrown by the delegate callback.
+ public static void AddRangeIf(
+ this ICollection collection,
+ IEnumerable itemsToAdd,
+ Func condition)
+ {
+ if (condition == null)
+ {
+ throw new ArgumentNullException(nameof(condition));
+ }
+
+ if (condition())
+ {
+ collection.AddRange(itemsToAdd);
+ }
+ }
+
///
/// Removes a collection of items from another.
///
@@ -148,6 +227,31 @@ public static void RemoveRange(this ICollection collection, IEnumerable
}
}
+ ///
+ /// Removes the specified collection of items from the collection based on the specified condition being true.
+ ///
+ /// The collection to remove the items from.
+ /// The items to remove.
+ /// The condition required to remove the items.
+ /// The type of item within the collection.
+ /// Thrown if the , or is .
+ /// Potentially thrown by the delegate callback.
+ public static void RemoveRangeIf(
+ this ICollection collection,
+ IEnumerable itemsToRemove,
+ Func condition)
+ {
+ if (condition == null)
+ {
+ throw new ArgumentNullException(nameof(condition));
+ }
+
+ if (condition())
+ {
+ collection.RemoveRange(itemsToRemove);
+ }
+ }
+
///
/// Determines whether two collections are equivalent, containing all the same items with no regard to order.
///
@@ -219,6 +323,7 @@ public static IEnumerable TakeFrom(this List list, int startingIndex, i
///
/// The action to perform.
///
+ /// Potentially thrown by the delegate callback.
public static void ForEach(this IEnumerable collection, Action action)
{
foreach (T item in collection)
@@ -262,6 +367,7 @@ public static int InsertAtPotentialIndex(this IList source, T value, Func<
/// The action to run to determine the position of the item based on the provided and an item in the collection.
/// The type of items in the collection.
/// The potential index of the item.
+ /// Potentially thrown by the delegate callback.
public static int PotentialIndexOf(this IList source, T value, Func predicate)
{
var result = 0;
@@ -279,5 +385,16 @@ public static int PotentialIndexOf(this IList source, T value, Func
+ /// Shuffles the elements of a sequence randomly.
+ ///
+ /// The collection to shuffle.
+ /// The type of item in the collection.
+ /// The shuffled collection of items.
+ public static IEnumerable Shuffle(this IEnumerable source)
+ {
+ return source.OrderBy(x => Guid.NewGuid());
+ }
}
}
\ No newline at end of file
diff --git a/src/MADE.Collections/ObjectModel/ObservableItemCollection{T}.cs b/src/MADE.Collections/ObjectModel/ObservableItemCollection{T}.cs
index bbe7ae25..4eb1e81d 100644
--- a/src/MADE.Collections/ObjectModel/ObservableItemCollection{T}.cs
+++ b/src/MADE.Collections/ObjectModel/ObservableItemCollection{T}.cs
@@ -27,6 +27,7 @@ public class ObservableItemCollection : ObservableCollection, IDisposable
///
/// Initializes a new instance of the class that is empty and has a default initial capacity.
///
+ /// Potentially thrown by the callback.
public ObservableItemCollection()
{
base.CollectionChanged += (s, e) =>
@@ -46,6 +47,7 @@ public ObservableItemCollection()
/// The collection whose elements are copied to the new list.
///
/// The collection parameter cannot be null.
+ /// Potentially thrown by the callback.
public ObservableItemCollection(IEnumerable collection)
: base(collection)
{
@@ -65,6 +67,7 @@ public ObservableItemCollection(IEnumerable collection)
/// The list whose elements are copied to the new list.
///
/// The list parameter cannot be null.
+ /// Potentially thrown by the callback.
public ObservableItemCollection(List list)
: base(list)
{
@@ -93,6 +96,7 @@ public ObservableItemCollection(List list)
///
/// The objects to add to the end of the collection.
///
+ /// Potentially thrown by the callback.
public void AddRange(IEnumerable items)
{
this.CheckDisposed();
@@ -117,6 +121,7 @@ public void AddRange(IEnumerable items)
///
/// The objects to remove from the collection.
///
+ /// Potentially thrown by the callback.
public void RemoveRange(IEnumerable items)
{
this.CheckDisposed();
diff --git a/src/MADE.Data.Converters/BooleanToStringValueConverter.Windows.cs b/src/MADE.Data.Converters/BooleanToStringValueConverter.Windows.cs
index 156d221b..eb926d81 100644
--- a/src/MADE.Data.Converters/BooleanToStringValueConverter.Windows.cs
+++ b/src/MADE.Data.Converters/BooleanToStringValueConverter.Windows.cs
@@ -80,7 +80,7 @@ public object Convert(object value, Type targetType, object parameter, string la
/// The converted object.
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
- if (!(value is string b))
+ if (value is not string b)
{
return value;
}
diff --git a/src/MADE.Data.Converters/Constants/DateTimeConstants.cs b/src/MADE.Data.Converters/Constants/DateTimeConstants.cs
index 77344619..9e34e717 100644
--- a/src/MADE.Data.Converters/Constants/DateTimeConstants.cs
+++ b/src/MADE.Data.Converters/Constants/DateTimeConstants.cs
@@ -7,6 +7,11 @@ namespace MADE.Data.Converters.Constants
///
public static class DateTimeConstants
{
+ ///
+ /// Defines the minimum value for a object determined by Unix.
+ ///
+ public static readonly DateTime UnixEpoch = new(1970, 1, 1, 0, 0, 0);
+
///
/// Defines the time at the end of a day.
///
diff --git a/src/MADE.Data.Converters/Extensions/DateTimeExtensions.cs b/src/MADE.Data.Converters/Extensions/DateTimeExtensions.cs
index 8abc3a74..76631d94 100644
--- a/src/MADE.Data.Converters/Extensions/DateTimeExtensions.cs
+++ b/src/MADE.Data.Converters/Extensions/DateTimeExtensions.cs
@@ -10,6 +10,30 @@ namespace MADE.Data.Converters.Extensions
///
public static class DateTimeExtensions
{
+ ///
+ /// Gets the day suffix for the specified date, i.e. st, nd, rd, or th.
+ ///
+ /// The date to get a day suffix for.
+ /// The day suffix as a string.
+ public static string ToDaySuffix(this DateTime dateTime)
+ {
+ switch (dateTime.Day)
+ {
+ case 1:
+ case 21:
+ case 31:
+ return "st";
+ case 2:
+ case 22:
+ return "nd";
+ case 3:
+ case 23:
+ return "rd";
+ default:
+ return "th";
+ }
+ }
+
///
/// Gets the current age in years based on the specified starting date and today's date.
///
@@ -206,7 +230,7 @@ public static DateTime EndOfYear(this DateTime dateTime)
///
public static DateTime? SetTime(this DateTime? dateTime, int hours, int minutes, int seconds, int milliseconds)
{
- return dateTime == null ? (DateTime?)null : SetTime(dateTime.Value, hours, minutes, seconds, milliseconds);
+ return dateTime == null ? null : SetTime(dateTime.Value, hours, minutes, seconds, milliseconds);
}
///
diff --git a/src/MADE.Data.Converters/Extensions/StringExtensions.cs b/src/MADE.Data.Converters/Extensions/StringExtensions.cs
index 11e0efbf..dc9aad44 100644
--- a/src/MADE.Data.Converters/Extensions/StringExtensions.cs
+++ b/src/MADE.Data.Converters/Extensions/StringExtensions.cs
@@ -3,7 +3,10 @@
namespace MADE.Data.Converters.Extensions
{
+ using System;
+ using System.IO;
using System.Text;
+ using System.Threading.Tasks;
///
/// Defines a collection of extensions for string values.
@@ -39,6 +42,28 @@ public static string ToTitleCase(this string value)
return result.ToString();
}
+ ///
+ /// Truncates a string value to the specified length with an ellipsis.
+ ///
+ /// The value to truncate.
+ /// The maximum length of the value.
+ /// A truncated string with ellipsis if the value's length is greater than the .
+ public static string Truncate(this string value, int maxLength)
+ {
+ if (string.IsNullOrEmpty(value))
+ {
+ return string.Empty;
+ }
+
+ if (value.Length <= maxLength)
+ {
+ return value;
+ }
+
+ const string suffix = "...";
+ return value.Substring(0, maxLength - suffix.Length) + suffix;
+ }
+
///
/// Converts a value to default case using the case rules of the invariant culture.
///
@@ -62,6 +87,48 @@ public static string ToDefaultCase(this string value)
return result;
}
+ ///
+ /// Converts a value to a Base64 string using the specified encoding.
+ ///
+ /// Default encoding is UTF-8.
+ ///
+ ///
+ /// The string value to convert.
+ /// The encoding to get the value bytes while converting.
+ /// The Base64 string representing the value.
+ public static string ToBase64(this string value, Encoding encoding = default)
+ {
+ encoding ??= Encoding.UTF8;
+ return Convert.ToBase64String(encoding.GetBytes(value));
+ }
+
+ ///
+ /// Converts a Base64 string to a value using the specified encoding.
+ ///
+ /// The Base64 value to convert.
+ /// The encoding to get the value string while converting.
+ /// The string value representing the Base64 string.
+ public static string FromBase64(this string base64Value, Encoding encoding = default)
+ {
+ encoding ??= Encoding.UTF8;
+ return encoding.GetString(Convert.FromBase64String(base64Value));
+ }
+
+ ///
+ /// Converts a string value to a .
+ ///
+ /// The value to convert.
+ /// A representing the string value.
+ public static async Task ToMemoryStreamAsync(this string value)
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ await writer.WriteAsync(value);
+ await writer.FlushAsync();
+ stream.Position = 0;
+ return stream;
+ }
+
///
/// Converts a string value to an integer.
///
@@ -99,7 +166,7 @@ public static int ToInt(this string value)
}
bool parsed = int.TryParse(value, out int intValue);
- return parsed ? (int?)intValue : null;
+ return parsed ? intValue : null;
}
///
@@ -159,7 +226,7 @@ public static float ToFloat(this string value)
}
bool parsed = float.TryParse(value, out float floatValue);
- return parsed ? (float?)floatValue : null;
+ return parsed ? floatValue : null;
}
///
@@ -199,7 +266,7 @@ public static double ToDouble(this string value)
}
bool parsed = double.TryParse(value, out double doubleValue);
- return parsed ? (double?)doubleValue : null;
+ return parsed ? doubleValue : null;
}
}
}
\ No newline at end of file
diff --git a/src/MADE.Data.Converters/StringToBase64StringValueConverter.cs b/src/MADE.Data.Converters/StringToBase64StringValueConverter.cs
new file mode 100644
index 00000000..5f9173a1
--- /dev/null
+++ b/src/MADE.Data.Converters/StringToBase64StringValueConverter.cs
@@ -0,0 +1,48 @@
+// MADE Apps licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace MADE.Data.Converters
+{
+ using System.Text;
+ using MADE.Data.Converters.Extensions;
+
+ ///
+ /// Defines a value converter from to Base64 with an optional Encoding parameter.
+ ///
+ public partial class StringToBase64StringValueConverter : IValueConverter
+ {
+ ///
+ /// Converts the value to the Base64 .
+ ///
+ ///
+ /// The value to convert.
+ ///
+ ///
+ /// The optional parameter used to help with conversion.
+ ///
+ ///
+ /// The converted Base64 object.
+ ///
+ public string Convert(string value, object parameter = default)
+ {
+ return value.ToBase64(parameter as Encoding ?? Encoding.UTF8);
+ }
+
+ ///
+ /// Converts the Base64 value back to the original value.
+ ///
+ ///
+ /// The value to convert.
+ ///
+ ///
+ /// The optional parameter used to help with conversion.
+ ///
+ ///
+ /// The converted object.
+ ///
+ public string ConvertBack(string value, object parameter = default)
+ {
+ return value.FromBase64(parameter as Encoding ?? Encoding.UTF8);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/MADE.Data.EFCore/Converters/UtcDateTimeConverter.cs b/src/MADE.Data.EFCore/Converters/UtcDateTimeConverter.cs
index 209eccec..62d9ea81 100644
--- a/src/MADE.Data.EFCore/Converters/UtcDateTimeConverter.cs
+++ b/src/MADE.Data.EFCore/Converters/UtcDateTimeConverter.cs
@@ -12,7 +12,7 @@ namespace MADE.Data.EFCore.Converters
public static class UtcDateTimeConverter
{
internal static readonly ValueConverter UtcConverter =
- new ValueConverter(
+ new(
value => value,
value => DateTime.SpecifyKind(value, DateTimeKind.Utc));
diff --git a/src/MADE.Data.EFCore/EntityBase.cs b/src/MADE.Data.EFCore/EntityBase.cs
index e4513bc9..05c04fc2 100644
--- a/src/MADE.Data.EFCore/EntityBase.cs
+++ b/src/MADE.Data.EFCore/EntityBase.cs
@@ -1,6 +1,7 @@
namespace MADE.Data.EFCore
{
using System;
+ using System.ComponentModel.DataAnnotations.Schema;
///
/// Defines a base definition for an entity.
@@ -10,6 +11,7 @@ public abstract class EntityBase : IEntityBase
///
/// Gets or sets the identifier of the entity.
///
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
///
diff --git a/src/MADE.Data.EFCore/Extensions/DbContextExtensions.cs b/src/MADE.Data.EFCore/Extensions/DbContextExtensions.cs
index 4ce3f5db..07213721 100644
--- a/src/MADE.Data.EFCore/Extensions/DbContextExtensions.cs
+++ b/src/MADE.Data.EFCore/Extensions/DbContextExtensions.cs
@@ -26,6 +26,7 @@ public static class DbContextExtensions
/// A concurrency violation is encountered while saving to the database.
/// A concurrency violation occurs when an unexpected number of rows are affected during save.
/// This is usually because the data in the database has been modified since it was loaded into memory.
+ /// If the is canceled.
public static async Task UpdateAsync(
this DbContext context,
T entity,
@@ -61,7 +62,7 @@ public static void SetEntityDates(this DbContext context)
.Entries()
.Where(
entry => entry.Entity is IEntityBase &&
- (entry.State == EntityState.Added || entry.State == EntityState.Modified));
+ entry.State is EntityState.Added or EntityState.Modified);
DateTime now = DateTime.UtcNow;
@@ -86,6 +87,8 @@ public static void SetEntityDates(this DbContext context)
///
/// True if the changes saved successfully; otherwise, false.
///
+ /// If the is canceled.
+ /// Potentially thrown by the delegate callback.
public static async Task TrySaveChangesAsync(
this DbContext context,
Action onError = null,
@@ -112,6 +115,7 @@ public static async Task TrySaveChangesAsync(
/// An exception for handling the exception thrown, for example, event logging.
/// The type of data context.
/// True if the action ran successfully; otherwise, false.
+ /// Potentially thrown by the delegate callback.
public static async Task TryAsync(
this TContext context,
Func action,
diff --git a/src/MADE.Data.EFCore/Extensions/EntityBaseExtensions.cs b/src/MADE.Data.EFCore/Extensions/EntityBaseExtensions.cs
index bff9bd38..b4e3388c 100644
--- a/src/MADE.Data.EFCore/Extensions/EntityBaseExtensions.cs
+++ b/src/MADE.Data.EFCore/Extensions/EntityBaseExtensions.cs
@@ -8,18 +8,33 @@ namespace MADE.Data.EFCore.Extensions
///
public static class EntityBaseExtensions
{
+ ///
+ /// Configures the default properties of an entity.
+ ///
+ /// The type of entity to configure.
+ /// The entity type builder associated with the entity.
+ /// The entity type builder.
+ public static EntityTypeBuilder Configure(this EntityTypeBuilder builder)
+ where TEntity : class, IEntityBase
+ {
+ builder.HasKey(e => e.Id);
+ builder.ConfigureDateProperties();
+ return builder;
+ }
+
///
/// Configures the created and updated date properties of an entity as UTC.
///
/// The type of entity to configure.
/// The entity type builder associated with the entity.
/// The entity type builder.
- public static EntityTypeBuilder ConfigureDateProperties(this EntityTypeBuilder builder)
- where TEntity : EntityBase
+ public static EntityTypeBuilder ConfigureDateProperties(
+ this EntityTypeBuilder builder)
+ where TEntity : class, IEntityBase
{
builder.Property(x => x.CreatedDate).IsUtc();
builder.Property(x => x.UpdatedDate).IsUtc();
return builder;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/MADE.Data.EFCore/MADE.Data.EFCore.csproj b/src/MADE.Data.EFCore/MADE.Data.EFCore.csproj
index dd6031c4..5359b7a6 100644
--- a/src/MADE.Data.EFCore/MADE.Data.EFCore.csproj
+++ b/src/MADE.Data.EFCore/MADE.Data.EFCore.csproj
@@ -15,11 +15,11 @@
-
+
-
+
diff --git a/src/MADE.Data.Validation/Extensions/DateTimeExtensions.cs b/src/MADE.Data.Validation/Extensions/DateTimeExtensions.cs
index 083b0bf0..9c4d77bc 100644
--- a/src/MADE.Data.Validation/Extensions/DateTimeExtensions.cs
+++ b/src/MADE.Data.Validation/Extensions/DateTimeExtensions.cs
@@ -26,7 +26,7 @@ public static bool IsInRange(this DateTime date, DateTime from, DateTime to)
/// True if the day of week is between Monday and Friday; otherwise, false.
public static bool IsWeekday(this DateTime date)
{
- return date.DayOfWeek >= DayOfWeek.Monday && date.DayOfWeek <= DayOfWeek.Friday;
+ return date.DayOfWeek is >= DayOfWeek.Monday and <= DayOfWeek.Friday;
}
///
@@ -36,7 +36,7 @@ public static bool IsWeekday(this DateTime date)
/// True if the day of week is Saturday or Sunday; otherwise, false.
public static bool IsWeekend(this DateTime date)
{
- return date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
+ return date.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday;
}
}
}
\ No newline at end of file
diff --git a/src/MADE.Data.Validation/Extensions/MathExtensions.cs b/src/MADE.Data.Validation/Extensions/MathExtensions.cs
index 6fdaebd9..2be9b89f 100644
--- a/src/MADE.Data.Validation/Extensions/MathExtensions.cs
+++ b/src/MADE.Data.Validation/Extensions/MathExtensions.cs
@@ -3,6 +3,7 @@
namespace MADE.Data.Validation.Extensions
{
+ using System;
using MADE.Data.Validation.Exceptions;
///
@@ -26,7 +27,7 @@ public static class MathExtensions
///
public static bool IsZero(this double value)
{
- return System.Math.Abs(value) < Epsilon;
+ return Math.Abs(value) < Epsilon;
}
///
@@ -40,7 +41,7 @@ public static bool IsZero(this double value)
///
public static bool IsZero(this float value)
{
- return System.Math.Abs(value) < Epsilon;
+ return Math.Abs(value) < Epsilon;
}
///
@@ -55,14 +56,15 @@ public static bool IsZero(this float value)
///
/// True if the values are close; otherwise, false.
///
+ /// Thrown if the value equals .
public static bool IsCloseTo(this int value, int compare)
{
- if (System.Math.Abs(value - compare) < 1)
+ if (Math.Abs(value - compare) < 1)
{
return true;
}
- double a = (System.Math.Abs(value) + System.Math.Abs(compare) + 10.0) * Epsilon;
+ double a = (Math.Abs(value) + Math.Abs(compare) + 10.0) * Epsilon;
int b = value - compare;
return -a < b && a > b;
}
@@ -81,12 +83,12 @@ public static bool IsCloseTo(this int value, int compare)
///
public static bool IsCloseTo(this double value, double compare)
{
- if (System.Math.Abs(value - compare) < Epsilon)
+ if (Math.Abs(value - compare) < Epsilon)
{
return true;
}
- double a = (System.Math.Abs(value) + System.Math.Abs(compare) + 10.0) * Epsilon;
+ double a = (Math.Abs(value) + Math.Abs(compare) + 10.0) * Epsilon;
double b = value - compare;
return -a < b && a > b;
}
@@ -110,12 +112,12 @@ public static bool IsCloseTo(this double? value, double? compare)
return false;
}
- if (System.Math.Abs(value.Value - compare.Value) < Epsilon)
+ if (Math.Abs(value.Value - compare.Value) < Epsilon)
{
return true;
}
- double a = (System.Math.Abs(value.Value) + System.Math.Abs(compare.Value) + 10.0) * Epsilon;
+ double a = (Math.Abs(value.Value) + Math.Abs(compare.Value) + 10.0) * Epsilon;
double? b = value - compare;
return -a < b && a > b;
}
@@ -134,12 +136,12 @@ public static bool IsCloseTo(this double? value, double? compare)
///
public static bool IsCloseTo(this float value, float compare)
{
- if (System.Math.Abs(value - compare) < Epsilon)
+ if (Math.Abs(value - compare) < Epsilon)
{
return true;
}
- double a = (System.Math.Abs(value) + System.Math.Abs(compare) + 10.0) * Epsilon;
+ double a = (Math.Abs(value) + Math.Abs(compare) + 10.0) * Epsilon;
float b = value - compare;
return -a < b && a > b;
}
@@ -163,12 +165,12 @@ public static bool IsCloseTo(this float? value, float? compare)
return false;
}
- if (System.Math.Abs(value.Value - compare.Value) < Epsilon)
+ if (Math.Abs(value.Value - compare.Value) < Epsilon)
{
return true;
}
- double a = (System.Math.Abs(value.Value) + System.Math.Abs(compare.Value) + 10.0) * Epsilon;
+ double a = (Math.Abs(value.Value) + Math.Abs(compare.Value) + 10.0) * Epsilon;
float? b = value - compare;
return -a < b && a > b;
}
diff --git a/src/MADE.Data.Validation/Extensions/StringExtensions.cs b/src/MADE.Data.Validation/Extensions/StringExtensions.cs
index 7a771735..7815c96f 100644
--- a/src/MADE.Data.Validation/Extensions/StringExtensions.cs
+++ b/src/MADE.Data.Validation/Extensions/StringExtensions.cs
@@ -3,8 +3,8 @@
namespace MADE.Data.Validation.Extensions
{
- using System;
using System.Globalization;
+ using System.Text.RegularExpressions;
///
/// Defines a collection of extensions for string values.
@@ -43,6 +43,43 @@ public static bool Contains(this string phrase, string value, CompareOptions com
return CultureInfo.CurrentCulture.CompareInfo.IndexOf(phrase, value, compareOption) >= 0;
}
+ ///
+ /// Compares a string value against a wildcard pattern, similar to the Visual Basic like operator.
+ ///
+ ///
+ /// An example of this in use comparing strings with * wildcard pattern.
+ ///
+ /// // result is true
+ /// bool result = "MyValue".IsLike("My*");
+ /// // result is false
+ /// result = "MyValue".IsLike("Hello");
+ ///
+ ///
+ /// The value to compare is like.
+ /// The wildcard like pattern to match on.
+ /// True if the value is like the pattern; otherwise, false.
+ /// Throw if a Regex time-out occurred.
+ public static bool IsLike(this string value, string likePattern)
+ {
+ if (value.IsNullOrWhiteSpace() || likePattern.IsNullOrWhiteSpace())
+ {
+ return false;
+ }
+
+ // Escape any special characters in pattern
+ var regex = "^" + Regex.Escape(likePattern) + "$";
+
+ // Replace wildcard characters with regular expression equivalents
+ regex = regex.Replace(@"\[!", "[^")
+ .Replace(@"\[", "[")
+ .Replace(@"\]", "]")
+ .Replace(@"\?", ".")
+ .Replace(@"\*", ".*")
+ .Replace(@"\#", @"\d");
+
+ return Regex.IsMatch(value, regex);
+ }
+
///
/// Checks whether a string value is an integer.
///
diff --git a/src/MADE.Data.Validation/ValidatorCollection.cs b/src/MADE.Data.Validation/ValidatorCollection.cs
index adb8a686..fca8d774 100644
--- a/src/MADE.Data.Validation/ValidatorCollection.cs
+++ b/src/MADE.Data.Validation/ValidatorCollection.cs
@@ -3,6 +3,7 @@
namespace MADE.Data.Validation
{
+ using System;
using System.Collections.Generic;
using System.Linq;
using MADE.Data.Validation.Extensions;
@@ -66,6 +67,7 @@ public bool IsDirty
/// Executes data validation on the provided against the validators provided.
///
/// The value to be validated.
+ /// Potentially thrown by the delegate callback.
public void Validate(object value)
{
this.ForEach(validator => validator.Validate(value));
diff --git a/src/MADE.Data.Validation/Validators/IpAddressValidator.cs b/src/MADE.Data.Validation/Validators/IpAddressValidator.cs
index b1cbd4ed..3fee521e 100644
--- a/src/MADE.Data.Validation/Validators/IpAddressValidator.cs
+++ b/src/MADE.Data.Validation/Validators/IpAddressValidator.cs
@@ -3,6 +3,7 @@
namespace MADE.Data.Validation.Validators
{
+ using System;
using System.Linq;
using System.Text.RegularExpressions;
using MADE.Data.Validation.Extensions;
@@ -43,6 +44,7 @@ public string FeedbackMessage
/// Executes data validation on the provided .
///
/// The value to be validated.
+ /// The array is multidimensional and contains more than elements.
public void Validate(object value)
{
string str = value?.ToString() ?? string.Empty;
@@ -54,7 +56,7 @@ public void Validate(object value)
private static bool IsNibbleValid(string nibble)
{
- if (nibble.Length > 3 || nibble.Length == 0)
+ if (nibble.Length is > 3 or 0)
{
return false;
}
@@ -70,7 +72,7 @@ private static bool IsNibbleValid(string nibble)
}
int.TryParse(nibble, out int numeric);
- return numeric >= 0 && numeric <= 255;
+ return numeric is >= 0 and <= 255;
}
}
}
\ No newline at end of file
diff --git a/src/MADE.Data.Validation/Validators/RegexValidator.cs b/src/MADE.Data.Validation/Validators/RegexValidator.cs
index 8b645fa1..fd6126fe 100644
--- a/src/MADE.Data.Validation/Validators/RegexValidator.cs
+++ b/src/MADE.Data.Validation/Validators/RegexValidator.cs
@@ -47,6 +47,7 @@ public virtual string FeedbackMessage
/// Executes data validation on the provided .
///
/// The value to be validated.
+ /// Thrown if a Regex time-out occurred.
public void Validate(object value)
{
string str = value?.ToString() ?? string.Empty;
diff --git a/src/MADE.Data.Validation/Validators/RequiredValidator.cs b/src/MADE.Data.Validation/Validators/RequiredValidator.cs
index 880c86c1..3858b5a1 100644
--- a/src/MADE.Data.Validation/Validators/RequiredValidator.cs
+++ b/src/MADE.Data.Validation/Validators/RequiredValidator.cs
@@ -34,7 +34,9 @@ public class RequiredValidator : IValidator
///
public string FeedbackMessage
{
- get => this.feedbackMessage.IsNullOrWhiteSpace() ? Resources.RequiredValidator_FeedbackMessage : this.feedbackMessage;
+ get => this.feedbackMessage.IsNullOrWhiteSpace()
+ ? Resources.RequiredValidator_FeedbackMessage
+ : this.feedbackMessage;
set => this.feedbackMessage = value;
}
@@ -50,19 +52,14 @@ public void Validate(object value)
private static bool DetermineIsInvalid(object value)
{
- switch (value)
+ return value switch
{
- case null:
- return true;
- case ICollection collection:
- return collection.Count <= 0;
- case bool isTrue:
- return !isTrue;
- case string str:
- return str.IsNullOrWhiteSpace();
- default:
- return false;
- }
+ null => true,
+ ICollection collection => collection.Count <= 0,
+ bool isTrue => !isTrue,
+ string str => str.IsNullOrWhiteSpace(),
+ _ => false
+ };
}
}
}
\ No newline at end of file
diff --git a/src/MADE.Diagnostics/AppDiagnostics.cs b/src/MADE.Diagnostics/AppDiagnostics.cs
index e3fd638b..fde4474b 100644
--- a/src/MADE.Diagnostics/AppDiagnostics.cs
+++ b/src/MADE.Diagnostics/AppDiagnostics.cs
@@ -64,7 +64,7 @@ public async Task StartRecordingDiagnosticsAsync()
#if WINDOWS_UWP
Windows.UI.Xaml.Application.Current.UnhandledException += this.OnAppUnhandledException;
#elif NETSTANDARD2_0 || __ANDROID__ || __IOS__
- System.AppDomain.CurrentDomain.UnhandledException += this.OnAppUnhandledException;
+ AppDomain.CurrentDomain.UnhandledException += this.OnAppUnhandledException;
#endif
#if __ANDROID__
@@ -92,7 +92,7 @@ public void StopRecordingDiagnostics()
#if WINDOWS_UWP
Windows.UI.Xaml.Application.Current.UnhandledException -= this.OnAppUnhandledException;
#elif NETSTANDARD2_0 || __ANDROID__ || __IOS__
- System.AppDomain.CurrentDomain.UnhandledException -= this.OnAppUnhandledException;
+ AppDomain.CurrentDomain.UnhandledException -= this.OnAppUnhandledException;
#endif
#if __ANDROID__
@@ -137,7 +137,7 @@ private void OnAppUnhandledException(object sender, UnhandledExceptionEventArgs
"The application is terminating due to an unhandled exception being thrown.");
}
- if (!(args.ExceptionObject is Exception ex))
+ if (args.ExceptionObject is not Exception ex)
{
return;
}
diff --git a/src/MADE.Diagnostics/Logging/FileEventLogger.cs b/src/MADE.Diagnostics/Logging/FileEventLogger.cs
index 4661daf0..23b5b21a 100644
--- a/src/MADE.Diagnostics/Logging/FileEventLogger.cs
+++ b/src/MADE.Diagnostics/Logging/FileEventLogger.cs
@@ -15,7 +15,7 @@ public class FileEventLogger : IEventLogger
{
private const string LogFormat = "{0:G}\tLevel: {1}\tId: {2}\tMessage: '{3}'";
- private readonly SemaphoreSlim fileSemaphore = new SemaphoreSlim(1, 1);
+ private readonly SemaphoreSlim fileSemaphore = new(1, 1);
///
/// Gets or sets the full file path to where the current log exists.
@@ -240,10 +240,8 @@ private async Task WriteToFileAsync(string line)
{
try
{
- using (StreamWriter sw = File.AppendText(this.LogPath))
- {
- await sw.WriteLineAsync(line);
- }
+ using StreamWriter sw = File.AppendText(this.LogPath);
+ await sw.WriteLineAsync(line);
}
catch (Exception ex)
{
diff --git a/src/MADE.Diagnostics/StopwatchHelper.cs b/src/MADE.Diagnostics/StopwatchHelper.cs
index 45e9959c..4c60007f 100644
--- a/src/MADE.Diagnostics/StopwatchHelper.cs
+++ b/src/MADE.Diagnostics/StopwatchHelper.cs
@@ -14,7 +14,7 @@ namespace MADE.Diagnostics
///
public static class StopwatchHelper
{
- private static readonly Dictionary Stopwatches = new Dictionary();
+ private static readonly Dictionary Stopwatches = new();
///
/// Starts a with the specified and .
diff --git a/src/MADE.Foundation/Platform/PlatformApiHelper.cs b/src/MADE.Foundation/Platform/PlatformApiHelper.cs
index 6e6aa2ef..93353f8d 100644
--- a/src/MADE.Foundation/Platform/PlatformApiHelper.cs
+++ b/src/MADE.Foundation/Platform/PlatformApiHelper.cs
@@ -9,9 +9,9 @@ namespace MADE.Foundation.Platform
///
public static class PlatformApiHelper
{
- private static readonly object Lock = new object();
+ private static readonly object Lock = new();
- private static readonly Dictionary CheckedTypes = new Dictionary();
+ private static readonly Dictionary CheckedTypes = new();
///
/// Indicates whether the specified is supported by the platform.
@@ -37,6 +37,7 @@ public static bool IsTypeSupported(Type type)
/// The type where the method should be checked.
/// The name of the method to check.
/// True if supported; otherwise, false.
+ /// More than one method is found with the specified name.
public static bool IsMethodSupported(Type type, string methodName)
{
var result = IsTypeSupported(type);
@@ -54,6 +55,7 @@ public static bool IsMethodSupported(Type type, string methodName)
/// The type where the property should be checked.
/// The name of the property to check.
/// True if supported; otherwise, false.
+ /// More than one property is found with the specified name.
public static bool IsPropertySupported(Type type, string propertyName)
{
var result = IsTypeSupported(type);
diff --git a/src/MADE.Networking/Http/Requests/Json/JsonDeleteNetworkRequest.cs b/src/MADE.Networking/Http/Requests/Json/JsonDeleteNetworkRequest.cs
index e3dc5e59..799fdc13 100644
--- a/src/MADE.Networking/Http/Requests/Json/JsonDeleteNetworkRequest.cs
+++ b/src/MADE.Networking/Http/Requests/Json/JsonDeleteNetworkRequest.cs
@@ -64,7 +64,7 @@ public JsonDeleteNetworkRequest(HttpClient client, string url, Dictionary
public override async Task ExecuteAsync(CancellationToken cancellationToken = default)
{
- string json = await this.GetJsonResponse(cancellationToken);
+ string json = await this.GetJsonResponseAsync(cancellationToken);
return JsonConvert.DeserializeObject(json);
}
@@ -84,11 +84,11 @@ public override async Task