diff --git a/src/Fluxera.DomainEvents.Abstractions/Fluxera.DomainEvents.Abstractions.csproj b/src/Fluxera.DomainEvents.Abstractions/Fluxera.DomainEvents.Abstractions.csproj
index de045f9..a620359 100644
--- a/src/Fluxera.DomainEvents.Abstractions/Fluxera.DomainEvents.Abstractions.csproj
+++ b/src/Fluxera.DomainEvents.Abstractions/Fluxera.DomainEvents.Abstractions.csproj
@@ -27,7 +27,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/src/Fluxera.DomainEvents.Abstractions/Guard.cs b/src/Fluxera.DomainEvents.Abstractions/Guard.cs
new file mode 100644
index 0000000..3c1e0f2
--- /dev/null
+++ b/src/Fluxera.DomainEvents.Abstractions/Guard.cs
@@ -0,0 +1,122 @@
+namespace Fluxera.DomainEvents.Abstractions
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Numerics;
+ using System.Runtime.CompilerServices;
+ using JetBrains.Annotations;
+
+ internal static class Guard
+ {
+ public static T ThrowIfNull(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 ThrowIfNullOrEmpty(IEnumerable 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 argument, [InvokerParameterName] [CallerArgumentExpression(nameof(argument))] string parameterName = null)
+ where T : INumber
+ {
+ 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.DomainEvents.MediatR/Fluxera.DomainEvents.MediatR.csproj b/src/Fluxera.DomainEvents.MediatR/Fluxera.DomainEvents.MediatR.csproj
index 4c0fec2..df81c7a 100644
--- a/src/Fluxera.DomainEvents.MediatR/Fluxera.DomainEvents.MediatR.csproj
+++ b/src/Fluxera.DomainEvents.MediatR/Fluxera.DomainEvents.MediatR.csproj
@@ -22,13 +22,12 @@
-
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/src/Fluxera.DomainEvents.MediatR/ServiceCollectionExtensions.cs b/src/Fluxera.DomainEvents.MediatR/ServiceCollectionExtensions.cs
index 72feafe..ed318fa 100644
--- a/src/Fluxera.DomainEvents.MediatR/ServiceCollectionExtensions.cs
+++ b/src/Fluxera.DomainEvents.MediatR/ServiceCollectionExtensions.cs
@@ -1,7 +1,6 @@
namespace Fluxera.DomainEvents.MediatR
{
using Fluxera.DomainEvents.Abstractions;
- using Fluxera.Guards;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -19,7 +18,7 @@ public static class ServiceCollectionExtensions
///
public static IServiceCollection AddDomainEvents(this IServiceCollection services)
{
- services = Guard.Against.Null(services);
+ services = Guard.ThrowIfNull(services);
// Register the default domain event dispatcher.
services.AddDomainEventDispatcher();
@@ -36,7 +35,7 @@ public static IServiceCollection AddDomainEvents(this IServiceCollection service
public static IServiceCollection AddDomainEventDispatcher(this IServiceCollection services)
where TDispatcher : MediatrDomainEventDispatcher
{
- services = Guard.Against.Null(services);
+ services = Guard.ThrowIfNull(services);
services.RemoveAll();
services.AddScoped();
diff --git a/src/Fluxera.DomainEvents/Fluxera.DomainEvents.csproj b/src/Fluxera.DomainEvents/Fluxera.DomainEvents.csproj
index 8888897..025e08f 100644
--- a/src/Fluxera.DomainEvents/Fluxera.DomainEvents.csproj
+++ b/src/Fluxera.DomainEvents/Fluxera.DomainEvents.csproj
@@ -22,13 +22,12 @@
-
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/src/Fluxera.DomainEvents/ServiceCollectionExtensions.cs b/src/Fluxera.DomainEvents/ServiceCollectionExtensions.cs
index cb7d586..5c0dd6c 100644
--- a/src/Fluxera.DomainEvents/ServiceCollectionExtensions.cs
+++ b/src/Fluxera.DomainEvents/ServiceCollectionExtensions.cs
@@ -1,7 +1,6 @@
namespace Fluxera.DomainEvents
{
using Fluxera.DomainEvents.Abstractions;
- using Fluxera.Guards;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -23,7 +22,7 @@ public static class ServiceCollectionExtensions
///
public static IServiceCollection AddDomainEvents(this IServiceCollection services)
{
- services = Guard.Against.Null(services);
+ services = Guard.ThrowIfNull(services);
// Register the default domain event dispatcher.
services.AddDomainEventDispatcher();
@@ -40,7 +39,7 @@ public static IServiceCollection AddDomainEvents(this IServiceCollection service
public static IServiceCollection AddDomainEventDispatcher(this IServiceCollection services)
where TDispatcher : DefaultDomainEventDispatcher
{
- services = Guard.Against.Null(services);
+ services = Guard.ThrowIfNull(services);
services.RemoveAll();
services.AddScoped();
@@ -56,7 +55,7 @@ public static IServiceCollection AddDomainEventDispatcher(this ISer
///
public static IServiceCollection AddDomainEventHandler(this IServiceCollection services)
{
- services = Guard.Against.Null(services);
+ services = Guard.ThrowIfNull(services);
Type type = typeof(TDomainEventHandler);
diff --git a/src/Fluxera.Entity/AggregateRoot.cs b/src/Fluxera.Entity/AggregateRoot.cs
index 6dfe6fc..31263ab 100644
--- a/src/Fluxera.Entity/AggregateRoot.cs
+++ b/src/Fluxera.Entity/AggregateRoot.cs
@@ -3,12 +3,8 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
- using Fluxera.ComponentModel.Annotations;
using Fluxera.DomainEvents.Abstractions;
using JetBrains.Annotations;
-#if NET6_0
- using Fluxera.Utilities.Extensions;
-#endif
///
/// A base class for aggregate roots.
@@ -25,7 +21,6 @@ public abstract class AggregateRoot : Entity
/// The domain events of this entity.
///
- [Ignore]
[IgnoreDataMember]
public IReadOnlyCollection DomainEvents => this.domainEvents.AsReadOnly();
diff --git a/src/Fluxera.Entity/Entity.cs b/src/Fluxera.Entity/Entity.cs
index 6294c89..7db85d3 100644
--- a/src/Fluxera.Entity/Entity.cs
+++ b/src/Fluxera.Entity/Entity.cs
@@ -5,7 +5,6 @@
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
- using Fluxera.ComponentModel.Annotations;
using JetBrains.Annotations;
///
@@ -36,7 +35,6 @@ public abstract class Entity
///
/// Gets a flag, if the entity instance is transient (not stored to the storage).
///
- [Ignore]
[IgnoreDataMember]
public virtual bool IsTransient
{
diff --git a/src/Fluxera.Entity/EnumerableExtensions.cs b/src/Fluxera.Entity/EnumerableExtensions.cs
new file mode 100644
index 0000000..5be4995
--- /dev/null
+++ b/src/Fluxera.Entity/EnumerableExtensions.cs
@@ -0,0 +1,24 @@
+#if NET6_0
+namespace Fluxera.Entity
+{
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.Linq;
+
+ internal static class EnumerableExtensions
+ {
+ ///
+ /// Converts the enumerable to a read-only collection.
+ ///
+ /// The type of the elements.
+ /// The collection to write-protect.
+ /// A write-protected collection.
+ public static IReadOnlyCollection AsReadOnly(this IEnumerable enumerable)
+ {
+ enumerable = Guard.ThrowIfNull(enumerable);
+
+ return new ReadOnlyCollection(enumerable.ToList());
+ }
+ }
+}
+#endif
diff --git a/src/Fluxera.Entity/Fluxera.Entity.csproj b/src/Fluxera.Entity/Fluxera.Entity.csproj
index 2ac169b..6036518 100644
--- a/src/Fluxera.Entity/Fluxera.Entity.csproj
+++ b/src/Fluxera.Entity/Fluxera.Entity.csproj
@@ -22,15 +22,12 @@
-
-
-
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/src/Fluxera.Entity/Guard.cs b/src/Fluxera.Entity/Guard.cs
new file mode 100644
index 0000000..525324d
--- /dev/null
+++ b/src/Fluxera.Entity/Guard.cs
@@ -0,0 +1,122 @@
+namespace Fluxera.Entity
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Numerics;
+ using System.Runtime.CompilerServices;
+ using JetBrains.Annotations;
+
+ internal static class Guard
+ {
+ public static T ThrowIfNull(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 ThrowIfNullOrEmpty(IEnumerable 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 argument, [InvokerParameterName] [CallerArgumentExpression(nameof(argument))] string parameterName = null)
+ where T : INumber
+ {
+ 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.Entity/PropertyAccessor.cs b/src/Fluxera.Entity/PropertyAccessor.cs
index c2a7b87..6758a0f 100644
--- a/src/Fluxera.Entity/PropertyAccessor.cs
+++ b/src/Fluxera.Entity/PropertyAccessor.cs
@@ -7,7 +7,6 @@ namespace Fluxera.Entity
using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;
- using Fluxera.Guards;
using JetBrains.Annotations;
[PublicAPI]
@@ -19,8 +18,8 @@ internal sealed class PropertyAccessor
private PropertyAccessor(string propertyName, Func