/// <summary> /// Execute the switch statement. Optionally ensure that one case statement was satisfied. /// </summary> private static void Do(object value, bool guaranteeHandling, SwitchCase[] cases) { #region Input Validation Insist.IsNotNull(cases, "cases"); Insist.AllItemsAreNotNull(cases, "cases"); Insist.ContainsAtLeast(cases, 1, "cases"); EnsureDefaultIsNotTheOnlyCase(cases); EnsureSingleDefaultCase(cases); EnsureDefaultIsLastCase(cases); EnsureFallThroughCaseIsNotTheLastCase(cases); #endregion CopyActionsToFallThroughCases(cases); bool handled = false; foreach (SwitchCase c in cases) { if (c.IsDefaultCase || object.Equals(value, c.ValueToTest)) { c.ActionToPerform(); handled = true; break; } } if (guaranteeHandling == true && handled == false) { throw new InvalidOperationException("No cases in this switch statement have been satisfied."); } }
/// <summary> /// Creates a new case. /// </summary> /// <param name="valueToTest"> /// The value to test for /// </param> /// <param name="actionToPerform"> /// The action to invoke if this case is satisfied /// </param> /// <returns> /// A new SwitchCase object /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if actionToPerform is null. /// </exception> public static SwitchCase Case(object valueToTest, Action actionToPerform) { Insist.IsNotNull(actionToPerform, "actionToPerform"); return(new SwitchCase(valueToTest, actionToPerform)); }
/// <summary> /// Validates an integral argument, throwing ArgumentException if it is more than the acceptable /// maximum value. /// </summary> /// <param name="value">The value to be validated.</param> /// <param name="argumentName">The argument name.</param> /// <param name="message">A message to include in the exception</param> /// <param name="maxValue">The maximum accepted value.</param> public static void IsAtMost <T>(T value, T maxValue, string argumentName, string message) where T : IComparable <T> { Insist.IsNotNull(value, "value"); if (value.CompareTo(maxValue) > 0) { throw new ArgumentOutOfRangeException(argumentName ?? "value", message ?? String.Format("The value must be less than or equal to {0}.", maxValue)); } }
/// <summary> /// Ensures that all items in the supplied collection do not consist only of null, empty or whitespace /// </summary> /// <param name="collection"> /// The collection to be validated. /// </param> /// <param name="argumentName"> /// The argument name. /// </param> /// <exception cref="System.ArgumentNullException"> /// If the collection itself is null /// </exception> /// <exception cref="System.ArgumentException"> /// If the collection contains a null value or a string.empty value or only whitespace /// </exception> public static void AllItemsAreNotNullOrWhitespace(IEnumerable <string> collection, string argumentName, string message) { Insist.IsNotNull(collection, "collection"); Insist.AllItemsSatisfyCondition( collection, (i) => { return(!string.IsNullOrWhiteSpace(i)); }, argumentName ?? "collection", message ?? "A null or string.empty item was found in the collection"); }
/// <summary> /// Ensures that all items in the supplied collection are not null /// </summary> /// <param name="collection"> /// The collection to be validated. /// </param> /// <param name="argumentName"> /// The argument name. /// </param> /// <exception cref="System.ArgumentNullException"> /// If the collection itself is null /// </exception> /// <exception cref="System.ArgumentException"> /// If the collection contains a null value /// </exception> public static void AllItemsAreNotNull <T>(IEnumerable <T> collection, string argumentName, string message) { Insist.IsNotNull(collection, "collection"); Insist.AllItemsSatisfyCondition( collection, (i) => { return(i != null); }, argumentName ?? "collection", message ?? "A null item was found in the collection"); }
/// <summary> /// Throws a <see cref="System.ArgumentException"/> if the argument value does /// not conform to the given predicate. /// </summary> /// <typeparam name="T">The argument type.</typeparam> /// <param name="argValue">The argument value.</param> /// <param name="predicate">The predicate.</param> /// <param name="argName">The argument name.</param> /// <param name="message">The message.</param> public static void Conforms <T>(T argValue, Predicate <T> predicate, string argName, string message) { Insist.IsNotNull(predicate, "predicate"); Insist.EvaluateArgument( () => { return(predicate(argValue)); }, argName, message, () => { return(CONFORMS_DEFAULT_MESSAGE); } ); }
/// <summary> /// Validates a type argument, throwing ArgumentException if it is not assignable from the specified type. /// </summary> /// <typeparam name="T">The type the argument must implement or inherit from.</typeparam> /// <param name="value">The type to be validated..</param> /// <param name="message">A message to include in the exception</param> /// <param name="argumentName">The argument name.</param> public static void IsAssignableFrom <T>(Type value, string argumentName, string message) { Insist.IsNotNull(value, "value"); if (!typeof(T).IsAssignableFrom(value)) { throw new ArgumentException( message ?? String.Format("The type {0} is not assignable from {1}.", value, typeof(T)), argumentName ?? "value"); } }
/// <summary> /// Throws an <see cref="System.ArgumentException"/> if the argument value /// does not match the expected value as defined by the given function. /// </summary> /// <typeparam name="T">The type of the argument.</typeparam> /// <param name="argValue">The argument value.</param> /// <param name="expectedValue">The expected value.</param> /// <param name="function">The comparison function to be used.</param> /// <param name="argName">The argument name.</param> /// <param name="message">The message.</param> public static void Is <T>(T argValue, T expectedValue, Func <T, T, bool> function, string argName, string message) { Insist.IsNotNull(function, "function"); Insist.EvaluateArgument( () => { return(function(argValue, expectedValue)); }, argName, message, () => { return(String.Format(IS_DEFAULT_MESSAGE, expectedValue)); } ); }
/// <summary> /// Throws an <see cref="System.InvalidOperationException"/> if the given argument value /// exists in the collection provided. /// </summary> /// <typeparam name="T">The type of the argument.</typeparam> /// <param name="argValue">The argument value.</param> /// <param name="disallowed">The collection of disallowed values.</param> /// <param name="argName">The argument name.</param> /// <param name="message">The message to be used.</param> public static void NotIn <T>(T argValue, IEnumerable <T> disallowed, string argName, string message) { Insist.IsNotNull(disallowed, "disallowed"); Insist.EvaluateArgument( () => { return(!disallowed.Contains(argValue)); }, argName, message, () => { return(NOT_IN_DEFAULT_MESSAGE); } ); }
/// <summary> /// Create new instance that will enumerate through the supplied set of enumerables /// </summary> public MultipleEnumerator(params IEnumerable <T>[] enumerables) { #region Input validation Insist.IsNotNull(enumerables, "enumerables"); Insist.IsNotEmpty(enumerables, "enumerables"); #endregion _enumerables = enumerables; }
/// <summary> /// Throws an <see cref="System.ArgumentException"/> if the given collection is empty. /// </summary> /// <typeparam name="T">The type of the collection.</typeparam> /// <param name="argValue">The argument value.</param> /// <param name="argName">The argument name.</param> /// <param name="message">The message.</param> public static void IsNotEmpty <T>(IEnumerable <T> argValue, string argName, string message) { Insist.IsNotNull(argValue, "argValue"); Insist.EvaluateArgument( () => { return(argValue.Count() > 0); }, argName, message, () => { return(COLLECTION_EMPTY_DEFAULT_MESSAGE); } ); }
/// <summary> /// Validates a integral argument, throwing ArgumentException if it falls outside /// the acceptable bounds. /// </summary> /// <param name="value">The value to be validated.</param> /// <param name="argumentName">The argument name.</param> /// <param name="message">A message to include in the exception</param> /// <param name="minValue">The minimum acceptable value.</param> /// <param name="maxValue">The maximum acceptable value.</param> public static void IsWithinBounds <T>(T value, T minValue, T maxValue, string argumentName, string message) where T : IComparable <T> { Insist.IsNotNull(value, "value"); if ((value.CompareTo(minValue) < 0) || (value.CompareTo(maxValue) > 0)) { throw new ArgumentException( message ?? (String.Format("The value must be between {0} and {1}.", minValue, maxValue)), argumentName ?? "value"); } }
/// <summary> /// Ensures that the collection contains at most the number of specified items /// </summary> /// <param name="collection"> /// The collection to be validated. /// </param> /// <param name="minNumberOfItems"> /// The maximum number of items that the collection must have /// </param> /// <param name="argumentName"> /// The argument name. /// </param> /// <exception cref="System.ArgumentNullException"> /// If the collection itself is null /// </exception> /// <exception cref="System.ArgumentException"> /// If the collection contains more than the minumum number of items. OR. the maxNumberOfItems /// argument is less than zero. /// </exception> public static void ContainsAtMost <T>(IEnumerable <T> collection, int maxNumberOfItems, string argumentName, string message) { Insist.IsNotNull(collection, "collection"); Insist.IsAtLeast(maxNumberOfItems, 0, "maxNumberOfItems"); if (CountItems(collection) > maxNumberOfItems) { throw new ArgumentException( message ?? "collection contains more than the maximum number of items", argumentName ?? "collection"); } }
/// <summary> /// Construct a new Failure OperationResult with the supplied list of error messages /// </summary> /// <param name="errorMessages"> /// The collection of error messages that indicate why the operation failed /// </param> /// <exception cref="System.ArgumentNullException"> /// Throw if /// errorMessages is null /// errorMessages contains a null element /// </exception> /// <exception cref="System.ArgumentException"> /// Throw if /// errorMessages contains no elements /// </exception> public OperationResult(ICollection <string> errorMessages) { #region Input Validation Insist.IsNotNull(errorMessages, "errorMessages"); Insist.ContainsAtLeast(errorMessages, 1, "errorMessages"); Insist.AllItemsAreNotNull(errorMessages, "errorMessages"); #endregion _success = false; _errorMessages = new List <string>(); _errorMessages.AddRange(errorMessages); }
/// <summary> /// Ensures that all items in the supplied collection satisfy the supplied predicate /// </summary> /// <param name="collection"> /// The collection to be validated. /// </param> /// <param name="predicate"> /// The predicate that is applied to every element in the collection /// </param> /// <param name="argumentName"> /// The argument name. /// </param> /// <exception cref="System.ArgumentNullException"> /// If the collection itself is null /// </exception> /// <exception cref="System.ArgumentException"> /// If the collection contains a value that violates a predicate /// </exception> public static void AllItemsSatisfyCondition <T>(IEnumerable <T> collection, Predicate <T> predicate, string argumentName, string message) { Insist.IsNotNull(collection, "collection"); Insist.IsNotNull(predicate, "predicate"); foreach (T obj in collection) { if (!predicate(obj)) { throw new ArgumentException( message ?? "An item was found in the collection that violates the predicate", argumentName ?? "collection"); } } }
/// <summary> /// Creates a new instance of a Disposer for the /// supplied instance and dispose action /// </summary> /// <param name="value"> /// The instance to wrap /// </param> /// <param name="entryAction"> /// An action to be performed when starting. /// </param> /// <param name="disposeAction"> /// The code that will get run when this Disposer is disposed. /// Used to cleanup the wrapped instance value. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if value or disposeAction are null /// </exception> private Disposer(T value, Action <T> entryAction, Action <T> disposeAction) { _log.DebugMethodCalled(value, disposeAction); #region Input validation Insist.IsNotNull(value, "value"); Insist.IsNotNull(disposeAction, "disposeAction"); #endregion _value = value; _isDisposed = false; _entryAction = entryAction; _disposeAction = disposeAction; }
/// <summary> /// Converts the supplied string to the Enum Type specified using the supplied parseMethod, /// optionally ignoring case /// </summary> /// <param name="toParse"> /// The string to convert into a byte /// </param> /// <param name="tryParseMethod"> /// The method that will be used to parse the string value /// </param> /// <param name="ignoreCase"> /// Whether or not to ignore the case during parsing. /// </param> /// <typeparam name="T"> /// The type that the string will be parsed into /// </typeparam> /// <returns> /// If conversion succeeded then the return value is a nullable object /// wrapping the T value. If conversion failed then the return value /// is null /// </returns> public static T?ToAny <T>(string toParse, EnumTryParseIgnoreCaseMethod <T> tryParseMethod, bool ignoreCase) where T : struct { #region Input validation Insist.IsNotNull(tryParseMethod, "tryParseMethod"); #endregion T val = default(T); if (tryParseMethod(toParse, ignoreCase, out val)) { return(new Nullable <T>(val)); } else { return(new Nullable <T>()); } }
/// <summary> /// Create a new NonNullable type that wraps the passed reference type /// </summary> /// <param name="value"> /// The reference type to wrap /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if value is null /// </exception> public NonNullable(T value) { Insist.IsNotNull(value, "value"); _value = value; }
/// <summary> /// Attempt to execute the supplied function. /// </summary> /// <param name="numberOfAttempts"> /// The number of attempts to try /// </param> /// <param name="interval"> /// The amount of time to wait inbetween attempts /// </param> /// <param name="functionToAttempt"> /// The function to try and execute /// </param> /// <param name="handleExceptions"> /// Whether or not to handle exceptions that get thrown as part of /// executing the supplied function. /// </param> /// <returns> /// An OperationResult that denotes whether or not the function succeeded. /// If the function succeeded then OperationResult.Succeeded is returned. /// If the function failed then a failure OperationResult is returned with /// details of the failuer and any thrown exceptions (if handleExceptions was true) /// </returns> /// <exception cref="System.ArgumentException"> /// Thrown if /// numberOfAttempts is less than 1 /// interval is less than 1 millisecond /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if /// functionToAttempt is null /// </exception> public static OperationResult Attempt( Func <bool> functionToAttempt, int numberOfAttempts, TimeSpan interval, RetryExceptionBehaviour exceptionBehaviour) { #region Input validation Insist.IsAtLeast(numberOfAttempts, 1, "numberOfAttempts"); Insist.IsAtLeast(interval, TimeSpan.FromMilliseconds(1), "interval"); Insist.IsNotNull(functionToAttempt, "functionToAttempt"); Insist.IsDefined <RetryExceptionBehaviour>(exceptionBehaviour, "exceptionBehaviour"); #endregion int currentAttempts = 0; List <Exception> thrownExceptions = new List <Exception>(); int numberOfThrownExceptions = 0; bool usingInfiniteAttempts = numberOfAttempts == INFINITE_ATTEMPTS; while (currentAttempts < numberOfAttempts) { bool success = false; try { success = functionToAttempt(); } catch (Exception e) { if (exceptionBehaviour == RetryExceptionBehaviour.DoNotHandle) { throw; } else if (exceptionBehaviour == RetryExceptionBehaviour.HandleAndCollate) { //Record the exception so that we can return information //about it later on. thrownExceptions.Add(e); numberOfThrownExceptions++; } else if (exceptionBehaviour == RetryExceptionBehaviour.HandleOnly) { numberOfThrownExceptions++; } else { throw new InvalidOperationException(string.Format("Unknown RetryExceptionBehaviour '{0}'", exceptionBehaviour)); } } if (success) { return(OperationResult.Succeeded); } if (!usingInfiniteAttempts) //If we're using an infinite number of attempts then //we don't want to make any progress regards number of //attempts. Just keep looping until the attempt succeeds. { currentAttempts++; } Thread.Sleep(interval); } //If we get to this point then all attempts have failed. List <string> errorMessages = new List <string>(); errorMessages.Add(string.Format("The function was not successfull after {0} attempts", numberOfAttempts)); if (numberOfThrownExceptions > 0) { if (exceptionBehaviour == RetryExceptionBehaviour.HandleAndCollate) { errorMessages.AddRange(thrownExceptions.Select(ex => ex.AllMessages())); } else if (exceptionBehaviour == RetryExceptionBehaviour.HandleOnly) { errorMessages.Add(string.Format(string.Format("A total of '{0}' exceptions were thrown during the attempt", numberOfThrownExceptions))); } } return(new OperationResult(errorMessages)); }
/// <summary> /// Validates a required argument, throwing an ArgumentNullException /// if it is null. /// </summary> /// <param name="value">The argument value to be validated.</param> /// <param name="argumentName">The argument name.</param> /// <exception cref="System.ArgumentNullException">If the value is null.</exception> public static void IsNotNull(Object value, string argumentName) { Insist.IsNotNull(value, argumentName, null); }