diff --git a/src/projects/EnsureThat/Ensure.cs b/src/projects/EnsureThat/Ensure.cs
index bc7a45a9..40c926df 100644
--- a/src/projects/EnsureThat/Ensure.cs
+++ b/src/projects/EnsureThat/Ensure.cs
@@ -7,7 +7,10 @@ namespace EnsureThat
{
public static class Ensure
{
- internal static readonly ExceptionFactory ExceptionFactory = new ExceptionFactory();
+ ///
+ /// Gets or Sets the Exception factory to use.
+ ///
+ public static IExceptionFactory ExceptionFactory { get; set; } = new ExceptionFactory();
///
/// Ensures for objects.
@@ -76,7 +79,7 @@ public static class Ensure
///
///
[Pure]
- public static Param That([NoEnumeration]T value, string name = null, OptsFn optsFn = null)
+ public static Param That([NoEnumeration] T value, string name = null, OptsFn optsFn = null)
=> new Param(name, value, optsFn);
///
@@ -90,7 +93,7 @@ public static Param That([NoEnumeration]T value, string name = null, OptsF
///
///
[Pure]
- public static StringParam That([NoEnumeration]string value, string name = null, OptsFn optsFn = null)
+ public static StringParam That([NoEnumeration] string value, string name = null, OptsFn optsFn = null)
=> new StringParam(name, value, optsFn);
///
@@ -122,4 +125,4 @@ public static TypeParam ThatTypeFor([NotNull] T value, string name = null, Op
public static TypeParam ThatType([NotNull] Type value, string name = null, OptsFn optsFn = null)
=> new TypeParam(name, value, optsFn);
}
-}
\ No newline at end of file
+}
diff --git a/src/projects/EnsureThat/EnsureOptions.cs b/src/projects/EnsureThat/EnsureOptions.cs
index 42595932..61e74a93 100644
--- a/src/projects/EnsureThat/EnsureOptions.cs
+++ b/src/projects/EnsureThat/EnsureOptions.cs
@@ -2,23 +2,42 @@
namespace EnsureThat
{
+ public delegate Exception CustomExceptionFactory(string message, string paramName);
+
public struct EnsureOptions
{
///
- /// If defined, this exception will be thrown instead of the
- /// standard exceptions for the particular ensure method.
+ /// If defined, this factory will be used to produce the exception that
+ /// will be thrown instead of the standard exceptions for the particular
+ /// ensure method.
+ /// Assign using .
+ ///
+ public CustomExceptionFactory CustomExceptionFactory { get; private set; }
+
+ ///
+ /// If defined, and no has been defined,
+ /// this exception will be thrown instead of the standard exceptions for the
+ /// particular ensure method.
/// Assign using .
///
public Exception CustomException { get; private set; }
///
- /// If defined, and no has been defined,
+ /// If defined, and neither
+ /// nor has been defined,
/// this message will be used instead of the standard message for the
/// particular ensure method.
/// Assign using .
///
public string CustomMessage { get; private set; }
+ public EnsureOptions WithExceptionFactory(CustomExceptionFactory factory)
+ {
+ CustomExceptionFactory = factory;
+
+ return this;
+ }
+
public EnsureOptions WithException(Exception ex)
{
CustomException = ex;
@@ -33,4 +52,4 @@ public EnsureOptions WithMessage(string message)
return this;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/projects/EnsureThat/Internals/ExceptionFactory.cs b/src/projects/EnsureThat/Internals/ExceptionFactory.cs
index 047a2dce..8b0fc879 100644
--- a/src/projects/EnsureThat/Internals/ExceptionFactory.cs
+++ b/src/projects/EnsureThat/Internals/ExceptionFactory.cs
@@ -3,11 +3,11 @@
namespace EnsureThat.Internals
{
- internal sealed class ExceptionFactory
+ internal sealed class ExceptionFactory : IExceptionFactory
{
[NotNull]
[Pure]
- internal Exception ArgumentException([NotNull] string defaultMessage, string paramName, OptsFn optsFn = null)
+ public Exception ArgumentException(string defaultMessage, string paramName, OptsFn optsFn = null)
{
if (optsFn != null)
{
@@ -25,12 +25,15 @@ internal Exception ArgumentException([NotNull] string defaultMessage, string par
[NotNull]
[Pure]
- internal Exception ArgumentNullException([NotNull] string defaultMessage, string paramName, OptsFn optsFn = null)
+ public Exception ArgumentNullException(string defaultMessage, string paramName, OptsFn optsFn = null)
{
if (optsFn != null)
{
var opts = optsFn(new EnsureOptions());
+ if (opts.CustomExceptionFactory != null)
+ return opts.CustomExceptionFactory(defaultMessage, paramName);
+
if (opts.CustomException != null)
return opts.CustomException;
@@ -43,7 +46,7 @@ internal Exception ArgumentNullException([NotNull] string defaultMessage, string
[NotNull]
[Pure]
- internal Exception ArgumentOutOfRangeException([NotNull] string defaultMessage, string paramName, TValue value, OptsFn optsFn = null)
+ public Exception ArgumentOutOfRangeException(string defaultMessage, string paramName, TValue value, OptsFn optsFn = null)
{
if (optsFn != null)
{
@@ -59,4 +62,4 @@ internal Exception ArgumentOutOfRangeException([NotNull] string defaultM
return new ArgumentOutOfRangeException(paramName, value, defaultMessage);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/projects/EnsureThat/Internals/IExceptionFactory.cs b/src/projects/EnsureThat/Internals/IExceptionFactory.cs
new file mode 100644
index 00000000..ce41ba3d
--- /dev/null
+++ b/src/projects/EnsureThat/Internals/IExceptionFactory.cs
@@ -0,0 +1,12 @@
+using System;
+using JetBrains.Annotations;
+
+namespace EnsureThat.Internals
+{
+ public interface IExceptionFactory
+ {
+ Exception ArgumentException([NotNull] string defaultMessage, string paramName, OptsFn optsFn = null);
+ Exception ArgumentNullException([NotNull] string defaultMessage, string paramName, OptsFn optsFn = null);
+ Exception ArgumentOutOfRangeException([NotNull] string defaultMessage, string paramName, TValue value, OptsFn optsFn = null);
+ }
+}
diff --git a/src/tests/UnitTests/OptsTests.cs b/src/tests/UnitTests/OptsTests.cs
index 27da7e95..33d6bd03 100644
--- a/src/tests/UnitTests/OptsTests.cs
+++ b/src/tests/UnitTests/OptsTests.cs
@@ -10,6 +10,44 @@ namespace UnitTests
{
public class OptsTests
{
+ public class WithCustomExceptionFactoryTests : UnitTestBase
+ {
+ [Fact]
+ public void ThrowsTheCustomExceptionFromTheFactory()
+ {
+ object value = null;
+ OptsFn options = o => o.WithExceptionFactory((_, __) => new KeyNotFoundException());
+
+ var actions = new Action[]
+ {
+ () => Ensure.Any.IsNotNull(value, ParamName, options),
+ () => EnsureArg.IsNotNull(value, ParamName, options),
+ () => Ensure.That(value, ParamName, options).IsNotNull()
+ }.ToList();
+
+ actions.ForEach(a => a.Should().Throw());
+ }
+
+ [Fact]
+ public void WhenWithMessageAndCustomExceptionAreSpecified_ThrowsTheCustomExceptionFromTheFactory()
+ {
+ object value = null;
+ OptsFn options = o => o
+ .WithMessage("Foo bar")
+ .WithException(new KeyNotFoundException())
+ .WithExceptionFactory((_, __) => new InvalidTimeZoneException());
+
+ var actions = new Action[]
+ {
+ () => Ensure.Any.IsNotNull(value, ParamName, options),
+ () => EnsureArg.IsNotNull(value, ParamName, options),
+ () => Ensure.That(value, ParamName,options).IsNotNull()
+ }.ToList();
+
+ actions.ForEach(a => a.Should().Throw().And.Message.Should().NotContain("Foo Bar"));
+ }
+ }
+
public class WithExceptionTests : UnitTestBase
{
[Fact]
@@ -60,4 +98,4 @@ public void ThrowsExceptionWithTheCustomMessage()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/tests/UnitTests/UnitTests.csproj b/src/tests/UnitTests/UnitTests.csproj
index 7564a555..e96df18d 100644
--- a/src/tests/UnitTests/UnitTests.csproj
+++ b/src/tests/UnitTests/UnitTests.csproj
@@ -1,7 +1,7 @@
- net452;netcoreapp2.1;netcoreapp3.1;net5.0
+ net452;netcoreapp3.1;net5.0
false
true