| master | dev |
|---|---|
A simple but flexible parameter validation library for .NET.
Starting with version 1.0.0 Silverlight is no longer supported.
This will throw an ArgumentException if text is empty or whitespace; an ArgumentNullException if
text is null; or an ArgumentOutOfRangeException if x is not greater than zero. In this case,
validation stops at the first broken rule and the corresponding exception gets thrown.
public void SomeMethod(string text, int x)
{
Require
.Parameter(nameof(text), text).IsNotNullOrWhiteSpace()
.AndParameter(nameof(x), x).IsGreaterThan(0);
}This does the same thing combining several validations for one parameter.
public void SomeMethod(string text, int x)
{
Require
.Parameter(nameof(text), text)
.IsNotNull()
.IsNotEmpty()
.IsNotWhiteSpace()
.AndParameter(nameof(x), x)
.IsGreaterThan(0);
}In that case you can use RequireAll for your validation, calling the Apply method at the end.
If one or more rules are broken, a Paravaly.ParameterValidationException will get thrown. This
exception inherits from AggregateException
and it will contain all relevant exceptions.
public void SomeMethod(string text, int x)
{
RequireAll
.Parameter(nameof(text), text).IsNotNullOrWhiteSpace()
.AndParameter(nameof(x), x).IsGreaterThan(0)
.Apply(); // Always call Apply when using RequireAll.
}It's very important to call the Apply method at the end or the exception won't get thrown and validation
will fail silently.
You can use this syntax.
public void SomeMethod(string text)
{
Require.Parameter(new { text }, text).IsNotNull();
}Just beware that it's a lot slower than using the string parameter (still a lot faster than using an
Expression though), but if performance is not an issue, it's better than hardcoded strings.
You can pass custom error messages to all validations.
public void SomeMethod(string text)
{
Require.Parameter(nameof(text), text).IsNotNull("Some custom error message.");
}You may use the following overload to improve performance when your error message is not a constant value (e.g. it comes from a resource file, you're concatenating strings, formatting, etc.).
public void SomeMethod(string text)
{
Require
.Parameter(nameof(text), text)
.IsNotNull(p => string.Format(Resources.SomeCustomErrorMessage, p.Name, p.Value));
}You can even use any exception you want.
public void SomeMethod(string text)
{
Require
.Parameter(nameof(text), text)
.IsNotNull(p => new ArgumentNullException(nameof(text)));
}Yes you can. You can create a new extension if you plan on reusing your validation logic. This is a sample custom rule for integer types.
public static IValidatingParameter<int> IsLessThan100(this IParameter<int> parameter)
{
return parameter.IsValid(
p =>
{
if (p.Value >= 100)
{
p.Handle(new ArgumentOutOfRangeException(
p.Name,
p.Value,
"The parameter value must be less than 100."));
}
});
}And you can use it just like any other validation rule.
public void SomeMethod(int x)
{
Require.Parameter(nameof(x), x).IsLessThan100();
}If you need something quick for a one time thing, you can use the IsValid method directly.
public void SomeMethod(int x)
{
Require
.Parameter(nameof(x), x)
.IsValid(
p =>
{
if (p.Value < 100)
{
p.Handle(new ArgumentOutOfRangeException(
p.Name,
p.Value,
"The parameter value must be less than 100."));
}
});
}Yes, just use the TypeParameter method.
public void SomeMethod<T>()
{
Require.TypeParameter<T>().IsInterface();
}If your type parameter's name is not 'T', you can specify the actual name.
public void SomeMethod<TInterface, TEnum>()
{
Require
.TypeParameter<TInterface>(nameof(TInterface)).IsInterface()
.AndTypeParameter<TEnum>(nameof(TEnum)).IsEnum();
}What if I want to disable validation (e.g. for unit testing) or I simply don't like using static methods?
You can inject one of the IRequire implementations instead of using the static methods. You can use
Require or RequireAll as you prefer for runtime, and the special class RequireNothing to disable validation.
public MyClass(IRequire require)
{
this.require = require;
}
private readonly IRequire require;
public void SomeMethod(string text)
{
this.require.Parameter(nameof(text), text).IsNotNull().Apply();
}All IRequire implementations are thread-safe, so it's safe to make them singletons.
Licensed under the Apache License, Version 2.0.