New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

RuleWeaver

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

RuleWeaver

A high-performance, async-capable object validation engine for .NET. Features a cached execution plan and allows non-blocking database validations (via ValueTask) based on rules defined in appsettings.json. Returns deterministic, structured error arrays, ideal for modern APIs.

Source
nugetNuGet
Version
1.0.7
Version published
Maintainers
1
Created
Source

🕸️ RuleWeaver

RuleWeaver logo

NuGet Build & Publish License: MIT

Validation without the boilerplate. A high-performance, configuration-driven, .NET 10–agnostic validation engine.

🚀 Why RuleWeaver?

Tired of creating repetitive Validator classes for every DTO? RuleWeaver eliminates the need for "robotic" validation coding.

  • Zero Validation Classes: Define rules directly in appsettings.json.
  • Enterprise-Grade Performance: Singleton cache of execution plans. JSON parsing happens only once; subsequent requests run entirely in memory (Zero I/O).
  • Async & Non-Blocking: Built on top of ValueTask to support database validations without blocking threads, while keeping zero-allocation for CPU-bound rules.
  • Deterministic: Structured and frontend-friendly error responses (Array of Objects).
  • Extensible: Create custom rules (e.g., IsCpf, UniqueEmail) in your API and RuleWeaver discovers them automatically.
  • Safe Dependency Injection: Architecture that respects scopes (Singleton Cache + Scoped Engine), safely allowing rules that access DbContext.

📦 Installation

Install via NuGet Package Manager Console:

Install-Package RuleWeaver

Or via .NET CLI: dotnet add package RuleWeaver

⚡ Quick Start

1. Register in Program.cs

In your Program.cs, register the service. The parameter typeof(Program).Assembly allows RuleWeaver to discover custom rules in your project.

using RuleWeaver.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Registers the Cache (Singleton) and the Engine (Scoped)
builder.Services.AddRuleWeaver(typeof(Program).Assembly);

builder.Services.AddControllers();
// ...

2. Define your DTO

Create the class you want to validate.

public class CustomerRequest
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
}

3. Configure the Rules (appsettings.json)

Use the RuleWeaver section to map your classes and properties.

{
  "RuleWeaver": {
    "CustomerRequest": {
      "Name": [
        {
          "RuleName": "Required",
          "RuleParameter": null,
          "RuleErrorMessage": "Name is required."
        },
        {
          "RuleName": "MinLength",
          "RuleParameter": "3"
        }
      ],
      "Age": [
        {
          "RuleName": "MinValue",
          "RuleParameter": "18",
          "RuleErrorMessage": "Not allowed for under 18."
        }
      ],
      "Email": [
        { "RuleName": "Required" },
        { "RuleName": "Email", "RuleErrorMessage": "Invalid email." }
      ]
    }
  }
}

4. Use in the Controller

Add the [WeaveValidation] attribute to your Action. The engine will validate the object before entering the method.

using Microsoft.AspNetCore.Mvc;
using RuleWeaver.Attributes;

[ApiController]
[Route("api/[controller]")]
public class CustomerController : ControllerBase
{
    [HttpPost]
    [WeaveValidation] // <--- The magic happens here
    public IActionResult Create([FromBody] CustomerRequest request)
    {
        // If execution reaches here, the request is already validated!
        return Ok();
    }
}

🛠️ Available Rules (Built-in)

The package already includes the following native rules:

| Rule Parameter | Ex    | Description                                    |
| -------------- | ----- | ---------------------------------------------- |
| Required       | —     | Checks if the value is not null or empty.      |
| MinLength      | 5     | Minimum length for Strings or Lists.           |
| MaxLength      | 100   | Maximum length for Strings or Lists.           |
| MinValue       | 18    | Minimum numeric value.                         |
| MaxValue       | 99    | Maximum numeric value.                         |
| Email          | —     | Validates email format (Regex).                |
| Regex          | [0-9] | Validates against a custom regular expression. |

🧩 Creating Custom Rules

Need to validate a specific ID format or check if an email exists in the database? Create a class implementing IValidationRule.

Note: RuleWeaver uses ValueTask to support high-performance async validations.

using RuleWeaver.Abstractions;
using System.Threading.Tasks;

public class UniqueEmailRule : IValidationRule
{
    private readonly MyDbContext _context; // Supports DI!

    public UniqueEmailRule(MyDbContext context)
    {
        _context = context;
    }

    public string Name => "UniqueEmail"; // Name used in JSON

    public async ValueTask<RuleResult> ValidateAsync(object? value, string[] args)
    {
        if (value is null) return RuleResult.Success();

        // Async database call without blocking threads
        var exists = await _context.Users.AnyAsync(u => u.Email == value.ToString());

        if (exists)
        {
            return RuleResult.Failure("Email already taken.");
        }

        return RuleResult.Success();
    }
}

In JSON:

"Email": [
  { "RuleName": "UniqueEmail" }
]

🪆 Validating Nested Objects

RuleWeaver supports deep validation for complex objects using the special rule "Nested". To validate a child object (e.g., an Address inside a Customer), you must explicitly tell the engine to dive into that property.

1. The Model Structure

public class AddressDto
{
    public string Street { get; set; }
    public string ZipCode { get; set; }
}

public class CustomerRequest
{
    public string Name { get; set; }
    public AddressDto BillingAddress { get; set; } // <--- Complex Object
}

2. The Configuration

Define the rules for the child object (AddressDto) at the root level of the configuration, just like any other class. Then, in the parent class (CustomerRequest), apply the Nested rule.

{
  "RuleWeaver": {
    "CustomerRequest": {
      "Name": [{ "RuleName": "Required" }],
      "BillingAddress": [
        { "RuleName": "Required" }, // Ensure object is not null
        { "RuleName": "Nested" } // <--- Triggers deep validation
      ]
    },
    // Rules for the child object are defined separately
    "AddressDto": {
      "Street": [{ "RuleName": "Required" }],
      "ZipCode": [{ "RuleName": "MinLength", "RuleParameter": "8" }]
    }
  }
}

3. The Result

Errors in nested properties are automatically flattened using Dot Notation, making it easy for frontends to map errors to fields.

{
  "property": "BillingAddress.Street",
  "violations": [
    {
      "rule": "Required",
      "message": "This field is required."
    }
  ]
}

📚 Validating Collections

RuleWeaver automatically detects if a property is a collection (List, Array, IEnumerable). When you apply the "Nested" rule to a list, the engine iterates through every item and tracks the index in the error output.

1. The Model Structure

public class ContactDto
{
    public string Type { get; set; } // e.g. "Email", "Phone"
    public string Value { get; set; }
}

public class CustomerRequest
{
    public string Name { get; set; }
    public List<ContactDto> Contacts { get; set; } // <--- List/Collection
}

2. The Configuration

Apply the "Nested" rule to the list property (Contacts). The engine handles the iteration logic.

{
  "RuleWeaver": {
    "CustomerRequest": {
      "Name": [{ "RuleName": "Required" }],
      "Contacts": [
        { "RuleName": "Nested" } // <--- Iterates and validates each item
      ]
    },
    // Define rules for the item type (ContactDto)
    "ContactDto": {
      "Type": [{ "RuleName": "Required" }],
      "Value": [{ "RuleName": "Required" }]
    }
  }
}

3. The Result

Errors in collections include the Index of the invalid item (e.g., [1]), allowing the frontend to pinpoint exactly which row in a grid or list has the error.

{
  "property": "Contacts[1].Value",
  "violations": [
    {
      "rule": "Required",
      "message": "This field is required."
    }
  ]
}

📡 Response Format (API)

RuleWeaver returns a 400 Bad Request with a deterministic and frontend-friendly JSON body.

{
  "message": "Validation errors occurred.",
  "errors": [
    {
      "property": "Age",
      "violations": [
        {
          "rule": "MinValue",
          "message": "Not allowed for under 18."
        }
      ]
    },
    {
      "property": "Password",
      "violations": [
        {
          "rule": "MinLength",
          "message": "Length must be at least 8 characters."
        },
        {
          "rule": "Regex",
          "message": "Needs at least one number"
        }
      ]
    }
  ]
}

🏛️ Architecture and Performance

RuleWeaver was designed for scalability:

Layer 1 (Singleton Cache): On startup, RuleWeaver reads appsettings.json, parses it, and compiles an Execution Plan. This happens only once.

Layer 2 (Scoped Engine): On each request, the engine simply consults the in-memory plan (O(1)) and executes the rules.

Layer 3 (Async Pipeline): It uses ValueTask to ensure zero-allocation for synchronous rules (CPU-bound) while fully supporting await for I/O-bound rules.

Result: Virtually zero overhead after the initial warm-up.

🤝 Contribution

Contributions are welcome! Feel free to open Issues or submit Pull Requests.

📄 License

This project is licensed under the MIT License.

Keywords

validation

FAQs

Package last updated on 18 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts