diff --git a/src/Umbraco.Core/Attempt.cs b/src/Umbraco.Core/Attempt.cs
index ca2bbe35fe..b5c7430974 100644
--- a/src/Umbraco.Core/Attempt.cs
+++ b/src/Umbraco.Core/Attempt.cs
@@ -7,160 +7,110 @@ namespace Umbraco.Core
///
public static class Attempt
{
+ // note:
+ // cannot rely on overloads only to differenciate between with/without status
+ // in some cases it will always be ambiguous, so be explicit w/ 'WithStatus' methods
+
///
/// Creates a successful attempt with a result.
///
- /// The type of the attempted operation result.
+ /// The type of the attempted operation result.
/// The result of the attempt.
/// The successful attempt.
- public static Attempt Succeed(T result)
+ public static Attempt Succeed(TResult result)
{
- return Attempt.Succeed(result);
+ return Attempt.Succeed(result);
+ }
+
+ ///
+ /// Creates a successful attempt with a result and a status.
+ ///
+ /// The type of the attempted operation result.
+ /// The type of the attempted operation status.
+ /// The status of the attempt.
+ /// The result of the attempt.
+ /// The successful attempt.
+ public static Attempt SucceedWithStatus(TStatus status, TResult result)
+ {
+ return Attempt.Succeed(status, result);
}
///
/// Creates a failed attempt with a result.
///
- /// The type of the attempted operation result.
+ /// The type of the attempted operation result.
/// The result of the attempt.
/// The failed attempt.
- public static Attempt Fail(T result)
+ public static Attempt Fail(TResult result)
{
- return Attempt.Fail(result);
+ return Attempt.Fail(result);
+ }
+
+ ///
+ /// Creates a failed attempt with a result and a status.
+ ///
+ /// The type of the attempted operation result.
+ /// The type of the attempted operation status.
+ /// The status of the attempt.
+ /// The result of the attempt.
+ /// The failed attempt.
+ public static Attempt FailWithStatus(TStatus status, TResult result)
+ {
+ return Attempt.Fail(status, result);
}
///
/// Creates a failed attempt with a result and an exception.
///
- /// The type of the attempted operation result.
+ /// The type of the attempted operation result.
/// The result of the attempt.
/// The exception causing the failure of the attempt.
/// The failed attempt.
- public static Attempt Fail(T result, Exception exception)
+ public static Attempt Fail(TResult result, Exception exception)
{
- return Attempt.Fail(result, exception);
+ return Attempt.Fail(result, exception);
+ }
+
+
+ ///
+ /// Creates a failed attempt with a result, an exception and a status.
+ ///
+ /// The type of the attempted operation result.
+ /// The type of the attempted operation status.
+ /// The status of the attempt.
+ /// The result of the attempt.
+ /// The exception causing the failure of the attempt.
+ /// The failed attempt.
+ public static Attempt FailWithStatus(TStatus status, TResult result, Exception exception)
+ {
+ return Attempt.Fail(status, result, exception);
}
///
/// Creates a successful or a failed attempt, with a result.
///
- /// The type of the attempted operation result.
- /// A value indicating whether the attempt is successful.
+ /// The type of the attempted operation result.
+ /// A value indicating whether the attempt is successful.
/// The result of the attempt.
/// The attempt.
- public static Attempt If(bool success, T result)
+ public static Attempt If(bool condition, TResult result)
{
- return Attempt.SucceedIf(success, result);
- }
-
-
- ///
- /// Executes an attempt function, with callbacks.
- ///
- /// The type of the attempted operation result.
- /// The attempt returned by the attempt function.
- /// An action to execute in case the attempt succeeds.
- /// An action to execute in case the attempt fails.
- /// The outcome of the attempt.
- /// Runs or depending on the
- /// whether the attempt function reports a success or a failure.
- public static Outcome Try(Attempt attempt, Action onSuccess, Action onFail = null)
- {
- if (attempt.Success)
- {
- onSuccess(attempt.Result);
- return Outcome.Success;
- }
-
- if (onFail != null)
- {
- onFail(attempt.Exception);
- }
-
- return Outcome.Failure;
+ return Attempt.If(condition, result);
}
///
- /// Represents the outcome of an attempt.
+ /// Creates a successful or a failed attempt, with a result.
///
- /// Can be a success or a failure, and allows for attempts chaining.
- public struct Outcome
+ /// The type of the attempted operation result.
+ /// The type of the attempted operation status.
+ /// A value indicating whether the attempt is successful.
+ /// The status of the successful attempt.
+ /// The status of the failed attempt.
+ /// The result of the attempt.
+ /// The attempt.
+ public static Attempt IfWithStatus(bool condition, TStatus succStatus, TStatus failStatus, TResult result)
{
- private readonly bool _success;
-
- ///
- /// Gets an outcome representing a success.
- ///
- public static readonly Outcome Success = new Outcome(true);
-
- ///
- /// Gets an outcome representing a failure.
- ///
- public static readonly Outcome Failure = new Outcome(false);
-
- private Outcome(bool success)
- {
- _success = success;
- }
-
- ///
- /// Executes another attempt function, if the previous one failed, with callbacks.
- ///
- /// The type of the attempted operation result.
- /// The attempt function to execute, returning an attempt.
- /// An action to execute in case the attempt succeeds.
- /// An action to execute in case the attempt fails.
- /// If it executes, returns the outcome of the attempt, else returns a success outcome.
- ///
- /// Executes only if the previous attempt failed, else does not execute and return a success outcome.
- /// If it executes, then runs or depending on the
- /// whether the attempt function reports a success or a failure.
- ///
- public Outcome OnFailure(Func> nextFunction, Action onSuccess, Action onFail = null)
- {
- return _success
- ? Success
- : ExecuteNextFunction(nextFunction, onSuccess, onFail);
- }
-
- ///
- /// Executes another attempt function, if the previous one succeeded, with callbacks.
- ///
- /// The type of the attempted operation result.
- /// The attempt function to execute, returning an attempt.
- /// An action to execute in case the attempt succeeds.
- /// An action to execute in case the attempt fails.
- /// If it executes, returns the outcome of the attempt, else returns a failed outcome.
- ///
- /// Executes only if the previous attempt succeeded, else does not execute and return a success outcome.
- /// If it executes, then runs or depending on the
- /// whether the attempt function reports a success or a failure.
- ///
- public Outcome OnSuccess(Func> nextFunction, Action onSuccess, Action onFail = null)
- {
- return _success
- ? ExecuteNextFunction(nextFunction, onSuccess, onFail)
- : Failure;
- }
-
- private static Outcome ExecuteNextFunction(Func> nextFunction, Action onSuccess, Action onFail = null)
- {
- var attempt = nextFunction();
-
- if (attempt.Success)
- {
- onSuccess(attempt.Result);
- return Success;
- }
-
- if (onFail != null)
- {
- onFail(attempt.Exception);
- }
-
- return Failure;
- }
+ return Attempt.If(condition, succStatus, failStatus, result);
}
-
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/AttemptOfT.cs b/src/Umbraco.Core/AttemptOfTResult.cs
similarity index 68%
rename from src/Umbraco.Core/AttemptOfT.cs
rename to src/Umbraco.Core/AttemptOfTResult.cs
index d9e2abb186..81268e4e5a 100644
--- a/src/Umbraco.Core/AttemptOfT.cs
+++ b/src/Umbraco.Core/AttemptOfTResult.cs
@@ -5,12 +5,12 @@ namespace Umbraco.Core
///
/// Represents the result of an operation attempt.
///
- /// The type of the attempted operation result.
+ /// The type of the attempted operation result.
[Serializable]
- public struct Attempt
+ public struct Attempt
{
///
- /// Gets a value indicating whether this was successful.
+ /// Gets a value indicating whether this was successful.
///
public bool Success { get; }
@@ -22,13 +22,13 @@ namespace Umbraco.Core
///
/// Gets the attempt result.
///
- public T Result { get; }
+ public TResult Result { get; }
// optimize, use a singleton failed attempt
- private static readonly Attempt Failed = new Attempt(false, default(T), null);
+ private static readonly Attempt Failed = new Attempt(false, default(TResult), null);
// private - use Succeed() or Fail() methods to create attempts
- private Attempt(bool success, T result, Exception exception)
+ private Attempt(bool success, TResult result, Exception exception)
{
Success = success;
Result = result;
@@ -39,9 +39,9 @@ namespace Umbraco.Core
/// Creates a successful attempt.
///
/// The successful attempt.
- public static Attempt Succeed()
+ public static Attempt Succeed()
{
- return new Attempt(true, default(T), null);
+ return new Attempt(true, default(TResult), null);
}
///
@@ -49,16 +49,16 @@ namespace Umbraco.Core
///
/// The result of the attempt.
/// The successful attempt.
- public static Attempt Succeed(T result)
+ public static Attempt Succeed(TResult result)
{
- return new Attempt(true, result, null);
+ return new Attempt(true, result, null);
}
///
/// Creates a failed attempt.
///
/// The failed attempt.
- public static Attempt Fail()
+ public static Attempt Fail()
{
return Failed;
}
@@ -68,9 +68,9 @@ namespace Umbraco.Core
///
/// The exception causing the failure of the attempt.
/// The failed attempt.
- public static Attempt Fail(Exception exception)
+ public static Attempt Fail(Exception exception)
{
- return new Attempt(false, default(T), exception);
+ return new Attempt(false, default(TResult), exception);
}
///
@@ -78,9 +78,9 @@ namespace Umbraco.Core
///
/// The result of the attempt.
/// The failed attempt.
- public static Attempt Fail(T result)
+ public static Attempt Fail(TResult result)
{
- return new Attempt(false, result, null);
+ return new Attempt(false, result, null);
}
///
@@ -89,9 +89,9 @@ namespace Umbraco.Core
/// The result of the attempt.
/// The exception causing the failure of the attempt.
/// The failed attempt.
- public static Attempt Fail(T result, Exception exception)
+ public static Attempt Fail(TResult result, Exception exception)
{
- return new Attempt(false, result, exception);
+ return new Attempt(false, result, exception);
}
///
@@ -99,9 +99,9 @@ namespace Umbraco.Core
///
/// A value indicating whether the attempt is successful.
/// The attempt.
- public static Attempt SucceedIf(bool condition)
+ public static Attempt If(bool condition)
{
- return condition ? new Attempt(true, default(T), null) : Failed;
+ return condition ? new Attempt(true, default(TResult), null) : Failed;
}
///
@@ -110,9 +110,9 @@ namespace Umbraco.Core
/// A value indicating whether the attempt is successful.
/// The result of the attempt.
/// The attempt.
- public static Attempt SucceedIf(bool condition, T result)
+ public static Attempt If(bool condition, TResult result)
{
- return new Attempt(condition, result, null);
+ return new Attempt(condition, result, null);
}
///
@@ -120,7 +120,7 @@ namespace Umbraco.Core
///
///
///
- public static implicit operator bool(Attempt a)
+ public static implicit operator bool(Attempt a)
{
return a.Success;
}
diff --git a/src/Umbraco.Core/AttemptOfTResultTStatus.cs b/src/Umbraco.Core/AttemptOfTResultTStatus.cs
new file mode 100644
index 0000000000..ca66b0a961
--- /dev/null
+++ b/src/Umbraco.Core/AttemptOfTResultTStatus.cs
@@ -0,0 +1,142 @@
+using System;
+
+namespace Umbraco.Core
+{
+ ///
+ /// Represents the result of an operation attempt.
+ ///
+ /// The type of the attempted operation result.
+ /// The type of the attempted operation status.
+ [Serializable]
+ public struct Attempt
+ {
+ ///
+ /// Gets a value indicating whether this was successful.
+ ///
+ public bool Success { get; }
+
+ ///
+ /// Gets the exception associated with an unsuccessful attempt.
+ ///
+ public Exception Exception { get; }
+
+ ///
+ /// Gets the attempt result.
+ ///
+ public TResult Result { get; }
+
+ ///
+ /// Gets the attempt status.
+ ///
+ public TStatus Status { get; }
+
+ // private - use Succeed() or Fail() methods to create attempts
+ private Attempt(bool success, TResult result, TStatus status, Exception exception)
+ {
+ Success = success;
+ Result = result;
+ Status = status;
+ Exception = exception;
+ }
+
+ ///
+ /// Creates a successful attempt.
+ ///
+ /// The status of the attempt.
+ /// The successful attempt.
+ public static Attempt Succeed(TStatus status)
+ {
+ return new Attempt(true, default(TResult), status, null);
+ }
+
+ ///
+ /// Creates a successful attempt with a result.
+ ///
+ /// The status of the attempt.
+ /// The result of the attempt.
+ /// The successful attempt.
+ public static Attempt Succeed(TStatus status, TResult result)
+ {
+ return new Attempt(true, result, status, null);
+ }
+
+ ///
+ /// Creates a failed attempt.
+ ///
+ /// The status of the attempt.
+ /// The failed attempt.
+ public static Attempt Fail(TStatus status)
+ {
+ return new Attempt(false, default(TResult), status, null);
+ }
+
+ ///
+ /// Creates a failed attempt with an exception.
+ ///
+ /// The status of the attempt.
+ /// The exception causing the failure of the attempt.
+ /// The failed attempt.
+ public static Attempt Fail(TStatus status, Exception exception)
+ {
+ return new Attempt(false, default(TResult), status, exception);
+ }
+
+ ///
+ /// Creates a failed attempt with a result.
+ ///
+ /// The status of the attempt.
+ /// The result of the attempt.
+ /// The failed attempt.
+ public static Attempt Fail(TStatus status, TResult result)
+ {
+ return new Attempt(false, result, status, null);
+ }
+
+ ///
+ /// Creates a failed attempt with a result and an exception.
+ ///
+ /// The status of the attempt.
+ /// The result of the attempt.
+ /// The exception causing the failure of the attempt.
+ /// The failed attempt.
+ public static Attempt Fail(TStatus status, TResult result, Exception exception)
+ {
+ return new Attempt(false, result, status, exception);
+ }
+
+ ///
+ /// Creates a successful or a failed attempt.
+ ///
+ /// A value indicating whether the attempt is successful.
+ /// The status of the successful attempt.
+ /// The status of the failed attempt.
+ /// The attempt.
+ public static Attempt If(bool condition, TStatus succStatus, TStatus failStatus)
+ {
+ return new Attempt(condition, default(TResult), condition ? succStatus : failStatus, null);
+ }
+
+ ///
+ /// Creates a successful or a failed attempt, with a result.
+ ///
+ /// A value indicating whether the attempt is successful.
+ /// The status of the successful attempt.
+ /// The status of the failed attempt.
+ /// The result of the attempt.
+ /// The attempt.
+ public static Attempt If(bool condition, TStatus succStatus, TStatus failStatus, TResult result)
+ {
+ return new Attempt(condition, result, condition ? succStatus : failStatus, null);
+ }
+
+ ///
+ /// Implicity operator to check if the attempt was successful without having to access the 'success' property
+ ///
+ ///
+ ///
+ public static implicit operator bool(Attempt a)
+ {
+ return a.Success;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 3ea3d79581..38f34e690d 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -69,7 +69,8 @@
-
+
+
diff --git a/src/Umbraco.Tests/AttemptTests.cs b/src/Umbraco.Tests/AttemptTests.cs
index a912fdf2a7..84d33c4351 100644
--- a/src/Umbraco.Tests/AttemptTests.cs
+++ b/src/Umbraco.Tests/AttemptTests.cs
@@ -7,36 +7,6 @@ namespace Umbraco.Tests
[TestFixture]
public class AttemptTests
{
- [Test]
- public void Chained_Attempts()
- {
- Attempt.Try(Attempt.Succeed("success!"),
- s => Assert.AreEqual("success!", s),
- exception => Assert.Fail("Should have been successful."))
-
- // previous one was a success so that one SHOULD NOT run
- // and report success
- .OnFailure(() => Attempt.Succeed(123),
- i => Assert.Fail("The previous attempt was successful!"),
- exception => Assert.Fail("The previous attempt was successful!"))
-
- // previous one did not run, last run was a success so that one SHOULD run
- // and report failure
- .OnSuccess(() => Attempt.Fail(new Exception("Failed!")),
- d => Assert.Fail("Should have failed."),
- exception => Assert.AreEqual("Failed!", exception.Message))
-
- // previous one did run and was a failure so that one SHOULD NOT run
- .OnSuccess(() => Attempt.Succeed(987),
- i => Assert.Fail("The previous attempt failed!"),
- exception => Assert.Fail("The previous attempt failed!"))
-
- // previous one did not run, last run was a failure so that one SHOULD run
- // then why does it run?
- .OnFailure(() => Attempt.Succeed("finished"),
- i => Assert.AreEqual("finished", i),
- exception => Assert.Fail("Should have been successful."));
- }
[Test]
public void AttemptIf()
diff --git a/src/Umbraco.Web/Models/DynamicPublishedContent.cs b/src/Umbraco.Web/Models/DynamicPublishedContent.cs
index 2dd1e338ea..4e64ba3564 100644
--- a/src/Umbraco.Web/Models/DynamicPublishedContent.cs
+++ b/src/Umbraco.Web/Models/DynamicPublishedContent.cs
@@ -198,7 +198,7 @@ namespace Umbraco.Web.Models
}
var value = PublishedContent.GetPropertyValue(name, recurse);
- return Attempt