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.