SkillAgentSearch skills...

ExpressiveAnnotations

Annotation-based conditional validation library.

Install / Use

/learn @jwaliszko/ExpressiveAnnotations
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

logo

<a id="expressiveannotations-annotation-based-conditional-validation">ExpressiveAnnotations<sup><sup><sup>[annotation-based conditional validation]</sup></sup></sup></a>

Build status Coverage status Release version License

A small .NET and JavaScript library which provides full-stack, annotation-based, conditional validation mechanisms.

Given attributes, powered by expressions engine, allow to forget about imperative way of step-by-step implementation of validation conditions in many cases. Since fields validation requirements are applied as metadata, domain-related code is more condensed.

Table of contents

<a id="what-is-the-context-behind-this-implementation">What is the context behind this work?</a>

There are number of cases where the concept of metadata is used for justified reasons. Attributes are one of the ways to associate complementary information with existing data. Such annotations may also define the correctness of data.

Declarative validation when compared to imperative approach seems to be more convenient in many cases. Clean, compact code - all validation logic defined within the model scope. Simple to write, obvious to read.

<a id="requiredif-vs-assertthat---where-is-the-difference">RequiredIf vs. AssertThat - where is the difference?</a>

  • RequiredIf - if value is not yet provided, check whether it is required (annotated field is required to be non-null, when given condition is satisfied),
  • AssertThat - if value is already provided, check whether the condition is met (non-null annotated field is considered as valid, when given condition is satisfied).

<a id="sample-projects-+-demo">Sample projects + demo</a>

ASP.NET MVC web sample is also hosted online - http://expressiveannotations.net/.

<a id="what-are-a-brief-examples-of-usage">What are a brief examples of usage?</a>

This section presents few exemplary code snippets. Sample projects in the section above contain much more comprehensive set of use cases.

using ExpressiveAnnotations.Attributes;

[RequiredIf("GoAbroad == true")]
public string PassportNumber { get; set; }

Above we are saying, that annotated field is required when condition given in the logical expression is satisfied (passport number is required, if go abroad field has true boolean value).

Simple enough, let's move to another variation:

[AssertThat("ReturnDate >= Today()")]
public DateTime? ReturnDate { get; set; }

By the usage of this attribute type, we are not validating field requirement as before - its value is allowed to be null this time. Nevertheless, if some value is already given, provided restriction needs to be satisfied (return date needs to be greater than or equal to the date returned by Today() built-in function).

As shown below, both types of attributes may be combined (moreover, the same type can be applied multiple times for a single field):

[RequiredIf("Details.Email != null")]
[RequiredIf("Details.Phone != null")]
[AssertThat("AgreeToContact == true")]
public bool? AgreeToContact { get; set; }

Literal translation means, that if either email or phone is provided, you are forced to authorize someone to contact with you (boolean value indicating contact permission has to be true). What is more, we can see that nested properties are supported by the expressions parser.

The complexity of expressions may be arbitrarily increased, e.g. take a brief look at the following construction:

[RequiredIf(@"GoAbroad == true
              && (
                     (NextCountry != 'Other' && NextCountry == Country)
                     || (Age > 24 && Age <= 55)
                 )")]
public string ReasonForTravel { get; set; }

Restriction above, despite being more specific than its predecessors, still can be quickly understood (reason for travel has to be provided if you plan to go abroad and, either want to visit the same definite country twice, or are between 25 and 55).

Conditional operations are supported (ternary operator defined). You can imply various assertions on specific field based on certain condition (or nested conditions), e.g.

[AssertThat("Switch == 'ON' ? Voltage1 == Voltage2 : true")]
public int Voltage1 { get; set; }

Here, when switch is ON, voltages must be equal - otherwise everything is OK. You could express the same statement without conditional operator, i.e.

[AssertThat("Switch == 'ON' && (Voltage1 == Voltage2) || (Switch != 'ON')")]

but it is less verbose.

<a id="declarative-vs-imperative-programming---what-is-it-about">Declarative vs. imperative programming - what is it about?</a>

With declarative programming you write logic that expresses what you want, bu

View on GitHub
GitHub Stars348
CategoryDevelopment
Updated5mo ago
Forks119

Languages

C#

Security Score

92/100

Audited on Oct 21, 2025

No findings