Skip to content

Repository files navigation

Triplex

NuGet downloads

Validation library inspired by the concepts of Secure by Design, by Dan Bergh Johnsson, Daniel Deogun, and Daniel Sawano (MEAP 2019 Manning Publications). (Preconditions, Postconditions, Invariants & Proto-Primitives at https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts)

Project's Code Health

Overall

Quality Gate Status

Ratings

SQALE RatingSQALE IndexReliability RatingSecurity Rating

Types of validations

Arguments

Remember that arguments are actual values to methods declared parameters. The utility class used to validate arguments is Triplex.Validations.Arguments. If an argument is invalid this utility will throw an System.ArgumentException or one of its derivatives.

Object's state

Sometimes we need to check internal state before or after certain operation to ensure preconditions and invariants respectively. To check for those we use Triplex.Validation.State utility. This one throws System.InvalidOperationException or one of its derivatives.


Motivations

  • Do reject bad input as soon as possible specially nulls.
  • Control data coming from public interfaces.
  • Help API creators to enforce code contracts.
  • Remove compiler warnings around null checks.

Design

For arguments, all checks imply a null check first. So if you see something like _value = Arguments.OrException(value); means "return the exact same value or throw an exception if it is null". By the same logic, Arguments.LessThan(value, other); means "return the exact same value if is less than other otherwise throw an exception, but if some argument value is null throw ArgumentNullException.

Examples

Removing Compiler Warnings

  1. Simle Email wrapper class with Warning

Email With Warning 1 of 2

(Fig. 01 - Email class showing warning)

Email With Warning 2 of 2

(Fig. 02 - Email class showing expanded warning)

  1. Same issue even when we declare argument as "non-nullable" string instead of string?

Email With Warning 1 of 2

(Fig. 03 - Email class showing even with non-null reference type)

  1. Removing warning using Arguments.OrException(value)

Email With Warning 1 of 2

(Fig. 04 - Issue solved using block style)

Email With Warning 1 of 2

(Fig. 05 - Issue solved using expression-method style)

Arguments

usingTriplex.Validations;publicsealedclassEmail{privatereadonlystring_value;publicEmail(stringvalue){//a) Simple form (param name for ArgumentException is automatically taken from 1st parameter)Arguments.OrException(value);//b) With custom message (param name for ArgumentException is automatically taken from 1st parameter)Arguments.OrExceptionWithMessage(value,"Invalid email");// Use value ensuring that it is not null now_value=value.ToLowerInvariant();// or use returned value from argument check _value=Arguments.OrException(value);//return same input (literally same reference) }// Collapse Check-Then-Assign pattern using returned value from checks.publicEmail(stringusername,stringdomain)=>_value=$"{Arguments.OrException(username)}@{Arguments.OrException(domain)}";}

All checks has two forms:

  1. Data and inferred argument name. Like Arguments.OrException(someArg);
  2. Data, custom message, and inferred argument name. Like Arguments.OrExceptionWithMessage(someArg, "Your custom exception message goes here");

If you need to use a different argument name, both forms support a last optional parameter:

  1. Arguments.OrException(someArg, "manualArgumentName");
  2. Arguments.OrExceptionWithMessage(someArg, "Custom ex. message", "manualArgumentName");

It is not required to use nameof(someArg) the following forms are equivalent

  1. Arguments.OrException(someArg);Arguments.OrException(someArg, nameof(someArg));
  2. Arguments.OrExceptionWithMessage(someArg, "Custom ex. message");Arguments.OrExceptionWithMessage(someArg, "Custom ex. message", nameof(someArg));

Object's state

usingTriplex.Validations;publicsealedclassMyList<T>{publicTRemove(intindex){//0. Pre-conditionState.IsTrue(_size>0,"Unable to remove elements when empty.");//1. ContractArguments.Between(index,0,_size-1,"Index out of bounds.");//2. Do your stuffTremoved=DoRemoveElementAt(index);//3. After removing size must be zero or greaterState.StillHolds(_size>=0,"Internal error, size must not be negative.");returnremoved;}}

State checks semantics:

  1. Preconditions: Is*(expression) where expression depends on the actual check. Could be boolean or just a value (like in State.IsNotNull(value)).
  2. Postconditions: Still*(expression) where expression depends on the actual check. Could be boolean or just a value.

There is no argument name, because State is used to validate objects internal state, as a hole, or invariants.

Contribute

We like to get help from everybody, if you want to contribute to this tool, found some issue or just want a feature request please read, first, the Contributing guide.

Where to start?

  1. Fork + Clone this repo
  2. Build and Run Tests locally
    1. Build only dotnet build
    2. Full clean, build and test dotnet clean && dotnet test /p:ExcludeByAttribute=GeneratedCode /p:CollectCoverage=true
  3. Incremental build and test (regular dev workflow)
    1. dotnet test /p:CollectCoverage=true

At the end of a test run you should see something like

+---------------------+------+--------+--------+
| Module | Line | Branch | Method |
+---------------------+------+--------+--------+
| Triplex.Validations | 100% | 100% | 100% |
+---------------------+------+--------+--------+
+---------+------+--------+--------+
|| Line | Branch | Method |
+---------+------+--------+--------+
| Total | 100% | 100% | 100% |
+---------+------+--------+--------+
| Average | 100% | 100% | 100% |
+---------+------+--------+--------+

You should maintain a 100% of test coverage, please do not submit Pull Requests if you are unable to do that. If you need help, or does not know how to achieve the expected coverage percentage please contact maintainers for advice.

About

Validation library inspired by the concepts of Secure by Design, by Dan Bergh Johnsson, Daniel Deogun, and Daniel Sawano (MEAP 2019 Manning Publications).

Topics

Resources

Code of conduct

Contributing

Stars

2 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages