Skip to content

Instantly share code, notes, and snippets.

@dperish
Created June 24, 2020 13:32
Show Gist options
  • Save dperish/025343b5f12ff29ac9bb15e1155c25cf to your computer and use it in GitHub Desktop.
Save dperish/025343b5f12ff29ac9bb15e1155c25cf to your computer and use it in GitHub Desktop.
Basic guard class in C#, which throws or provides method chaining on valid results
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.CompilerServices;
namespace PiotApi.Domain.Common
{
public class Guard
{
public static GuardResult For() => new GuardResult();
}
public class GuardResult
{
}
public static class GuardExtensions
{
public static GuardResult NullOrDefault<T>(
this GuardResult guardResult,
T value,
string parameterName = "Unspecified parameter",
[CallerMemberName] string member = null,
[CallerLineNumber] int line = 0)
{
if (value == null
|| value.Equals(default(T)))
{
throw new ArgumentOutOfRangeException(
$"{parameterName} in {member} on line {line}");
}
return guardResult;
}
public static GuardResult NullOrEmpty(
this GuardResult guardResult,
string value,
string parameterName = "Unspecified parameter",
[CallerMemberName] string member = null,
[CallerLineNumber] int line = 0)
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentOutOfRangeException(
$"{parameterName} in {member} on line {line}");
}
return guardResult;
}
public static GuardResult Null<T>(
this GuardResult guardResult,
T value,
string parameterName = "Unspecified parameter",
[CallerMemberName] string member = null,
[CallerLineNumber] int line = 0)
{
if (value == null)
{
throw new ArgumentNullException(
$"{parameterName} in {member} on line {line}");
}
return guardResult;
}
public static GuardResult EmptyEnumerable<T>(
this GuardResult guardResult,
T values,
string parameterName = "Unspecified parameter",
[CallerMemberName] string member = null,
[CallerLineNumber] int line = 0) where T : IEnumerable
{
guardResult.Null(values);
if (values.Cast<object>().Any(value => value != null))
{
return guardResult;
}
throw new IndexOutOfRangeException(
$"{parameterName} in {member} on line {line}");
}
public static GuardResult ValidationErrors<T>(
this GuardResult guardResult,
T value,
[CallerMemberName] string member = null,
[CallerLineNumber] int line = 0) where T : class
{
var validationResults = new List<ValidationResult>();
Validator.TryValidateObject(value, new ValidationContext(value), validationResults, true);
if (!validationResults.Any())
{
return guardResult;
}
var validationErrors = string.Join("\\n", validationResults.ToList().Select(x => x.ErrorMessage));
throw new ValidationException(
$"Validation errors were detected in {member} on line {line}: \\n{validationErrors}");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment