Minima.RuleEngine.Core 1.1.16

dotnet add package Minima.RuleEngine.Core --version 1.1.16
                    
NuGet\Install-Package Minima.RuleEngine.Core -Version 1.1.16
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Minima.RuleEngine.Core" Version="1.1.16" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Minima.RuleEngine.Core" Version="1.1.16" />
                    
Directory.Packages.props
<PackageReference Include="Minima.RuleEngine.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Minima.RuleEngine.Core --version 1.1.16
                    
#r "nuget: Minima.RuleEngine.Core, 1.1.16"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Minima.RuleEngine.Core@1.1.16
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Minima.RuleEngine.Core&version=1.1.16
                    
Install as a Cake Addin
#tool nuget:?package=Minima.RuleEngine.Core&version=1.1.16
                    
Install as a Cake Tool

RuleEngine.Core

Core rule engine library for .NET with Roslyn-based compilation, design-time metadata, and extensible execution flow. This package is designed for enterprise usage with versioning, audit logging, and extensibility.

Features

  • Rule Definition: Create rules with metadata, versioning, parameters, and status management
  • C# Expression Evaluation: Execute C# expressions using Roslyn scripting
  • Design-Time Metadata: Rule editor metadata, categories, and parameter definitions
  • Versioning: Create multiple versions of rules and activate specific versions
  • Audit Logging: Track rule executions with input/output and performance metrics
  • RuleManager Flow: IRuleManager + IRuleProvider orchestration
  • DEBUG_RULES: Optional PDB generation for debugging compiled rules
  • Extensible: Plugin architecture for custom rule evaluators

Quick Start

1. Install the Package

dotnet add package Minima.RuleEngine.Core

2. Register Services

using RuleEngine.Core.Extensions;
using RuleEngine.Sqlite.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Core services and design-time metadata
builder.Services.AddRuleEngine();
builder.Services.AddRuleEngineDesignTime();

// Add RuleEngine with SQLite persistence (optional)
builder.Services.AddRuleEngineWithSqlite("Data Source=ruleengine.db");

var app = builder.Build();

3. Create and Execute Rules

// Create a rule
var createRequest = new CreateRuleRequest
{
    Name = "Discount Rule",
    Description = "Applies discount based on order amount",
    Content = new RuleContent
    {
        PredicateExpression = "Input.Amount > 100",
        ResultExpression = "Input.Amount * 0.9" // 10% discount
    }
};

var rule = await ruleRepository.CreateAsync(createRequest);

// Activate the rule
await ruleRepository.ActivateVersionAsync(rule.Id, 1);

// Execute the rule
var result = await ruleEngine.EvaluateAsync(rule.Id, new { Amount = 150 });
// Result: 135 (150 * 0.9)

Architecture Overview

Core Components

  • IRuleEngine: Main interface for rule execution
  • IRuleRepository: Manages rule storage and retrieval
  • IRuleEvaluator: Executes rule logic (C# expressions by default)
  • IAuditRepository: Logs rule execution history

Data Model

public class RuleDefinition
{
    public string Id { get; set; }
    public string Name { get; set; }
    public int Version { get; set; }
    public RuleStatus Status { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
    public string[] Tags { get; set; }
    public string Description { get; set; }
    public RuleContent Content { get; set; }
    public Dictionary<string, object> Parameters { get; set; }
}

public class RuleContent
{
    public string PredicateExpression { get; set; }
    public string ResultExpression { get; set; }
    public string Language { get; set; } = "csharp";
    public Dictionary<string, object> Metadata { get; set; }
}

Usage Examples

Creating Rules

// Simple rule
var simpleRule = new CreateRuleRequest
{
    Name = "Age Check",
    Description = "Checks if person is adult",
    Content = new RuleContent
    {
        PredicateExpression = "Input.Age >= 18",
        ResultExpression = "true"
    }
};

// Complex rule with parameters
var complexRule = new CreateRuleRequest
{
    Name = "Price Calculator",
    Description = "Calculates price with tax and discount",
    Content = new RuleContent
    {
        PredicateExpression = "Input.BasePrice > 0",
        ResultExpression = "Input.BasePrice * (1 + Input.TaxRate) * (1 - Input.DiscountRate)"
    },
    Parameters = new Dictionary<string, object>
    {
        ["TaxRate"] = 0.08,
        ["DiscountRate"] = 0.05
    }
};

Rule Versioning

// Create a new version
var newVersion = new CreateVersionRequest
{
    Content = new RuleContent
    {
        PredicateExpression = "Input.Amount > 200", // Changed threshold
        ResultExpression = "Input.Amount * 0.85"    // Better discount
    },
    Activate = true // Activate immediately
};

await ruleRepository.CreateVersionAsync(ruleId, newVersion);

// Rollback to previous version
await ruleRepository.ActivateVersionAsync(ruleId, 1);

Execution History

// Get execution history
var history = await auditRepository.GetExecutionHistoryAsync(ruleId, limit: 50);

foreach (var audit in history)
{
    Console.WriteLine($"Executed at: {audit.ExecutedAt}");
    Console.WriteLine($"Success: {audit.Success}");
    Console.WriteLine($"Duration: {audit.Duration.TotalMilliseconds}ms");
    Console.WriteLine($"Input: {audit.Input}");
    Console.WriteLine($"Output: {audit.Output}");
}

Database Schema

The SQLite database contains the following tables:

  • Rules: Rule metadata (name, description, status, tags)
  • RuleVersions: Rule content and versioning information
  • RuleParameters: Additional parameters for rules
  • RuleExecutionAudits: Execution history and performance metrics

Migration and Seeding

Running Migrations

# Create migration
dotnet ef migrations add InitialCreate --project RuleEngine.Sqlite --startup-project YourApp

# Update database
dotnet ef database update --project RuleEngine.Sqlite --startup-project YourApp

Seeding Sample Data

// Add sample rules during application startup
var sampleRules = new[]
{
    new CreateRuleRequest
    {
        Name = "VIP Customer Discount",
        Description = "Special discount for VIP customers",
        Content = new RuleContent
        {
            PredicateExpression = "Input.IsVip == true",
            ResultExpression = "Input.Amount * 0.8"
        }
    },
    new CreateRuleRequest
    {
        Name = "Bulk Order Discount",
        Description = "Discount for bulk orders",
        Content = new RuleContent
        {
            PredicateExpression = "Input.Quantity >= 10",
            ResultExpression = "Input.Amount * 0.9"
        }
    }
};

foreach (var ruleRequest in sampleRules)
{
    var rule = await ruleRepository.CreateAsync(ruleRequest);
    await ruleRepository.ActivateVersionAsync(rule.Id, 1);
}

Design-Time Metadata

Design-time metadata drives rule editor UX (catalogs, parameters, categories).

var ruleRequest = new CreateRuleRequest
{
    Name = "Minimum Order Total",
    Description = "Order total must exceed a minimum threshold.",
    Content = new RuleContent
    {
        PredicateExpression = "Input.TotalAmount > 100m",
        ResultExpression = "true",
        Metadata = new Dictionary<string, object>
        {
            ["DesignTime"] = new DesignTimeMetadata
            {
                Name = "Order.MinTotal",
                Title = "Minimum Order Total",
                Description = "Checks if order total is above a threshold.",
                ExpressionFormat = "Input.TotalAmount > {0}",
                DisplayFormat = "Order total > {0} TL",
                IsPredicate = true,
                Parameters = new List<ParameterDefinition>
                {
                    new NumericParameter("Minimum Total")
                },
                Categories = new List<RuleCategoryMetadata>
                {
                    new RuleCategoryMetadata { Id = 1, Title = "Order" }
                }
            }
        }
    }
};

Design-time metadata is collected by MetadataManager (wired via AddRuleEngineDesignTime).

RuleManager Flow

Use the manager/provider flow if you need dynamic rule selection per input:

public sealed class MyRuleProvider : IRuleProvider
{
    public Task<RuleDefinition?> GetRuleDefinitionAsync(object input)
        => _repository.GetActiveVersionAsync("my_rule_id");

    public Task<bool> ValidateRuleAsync(RuleDefinition rule, object input)
        => Task.FromResult(true);
}

ruleManager.RegisterProvider("my_rule_type", new MyRuleProvider());
var result = await ruleManager.ExecuteRuleAsync("my_rule_type", input);

DEBUG_RULES (PDB)

To debug compiled rules, add DEBUG_RULES to your build defines. This enables Roslyn PDB generation but slows compilation.

NuGet Notes

  • Package: Minima.RuleEngine.Core
  • Supported frameworks: net8.0, net9.0, net10.0
  • Recent updates: design-time metadata catalog, RuleManager/IRuleProvider flow, DEBUG_RULES PDB support

Documentation

  • Getting started: ../../docs/getting-started.md
  • Architecture: ../../docs/architecture.md
  • Rule authoring: ../../docs/rule-authoring.md

Custom Evaluators

You can create custom rule evaluators by implementing IRuleEvaluator:

public class JavaScriptRuleEvaluator : IRuleEvaluator
{
    public async Task<RuleExecutionResult> EvaluateAsync(RuleDefinition rule, object input, CancellationToken cancellationToken = default)
    {
        // Implement JavaScript evaluation logic
        // using libraries like Jint or V8
    }

    public async Task<ValidationResult> ValidateAsync(RuleDefinition rule, object input)
    {
        // Implement validation logic
    }
}

// Register custom evaluator
services.AddRuleEngineWithSqlite<JavaScriptRuleEvaluator>("Data Source=ruleengine.db");

Performance Considerations

  • Caching: Rule definitions are cached in memory for fast access
  • Async Operations: All operations are async for better scalability
  • Connection Pooling: Entity Framework handles connection pooling automatically
  • Audit Logging: Can be disabled or configured for specific rules if needed

Error Handling

The rule engine provides comprehensive error handling:

var result = await ruleEngine.EvaluateAsync(ruleId, input);

if (!result.Success)
{
    Console.WriteLine($"Rule execution failed: {result.ErrorMessage}");
    Console.WriteLine($"Duration: {result.Duration.TotalMilliseconds}ms");
}

Testing

The library includes comprehensive unit tests and integration tests:

# Run all tests
dotnet test

# Run specific test project
dotnet test tests/RuleEngine.Core.Tests/
dotnet test tests/RuleEngine.Integration.Tests/

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

Recent Updates

  • Added design-time metadata parsing with categories and parameter definitions
  • Added IRuleManager/IRuleProvider orchestration flow
  • Added DEBUG_RULES PDB debugging support in RuleCompiler
  • Switched core serialization to System.Text.Json for rule metadata/parameters
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Minima.RuleEngine.Core:

Package Downloads
Minima.RuleEngine.Sqlite

SQLite persistence provider for RuleEngine with Entity Framework Core integration for .NET 8/9/10.

Minima.CampaignEngine.Core

Core campaign engine with rule-based system for .NET 8/9/10

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.16 170 1/15/2026
1.1.15 151 1/15/2026
1.1.11 148 12/29/2025
1.1.10 152 12/29/2025
1.1.9 147 12/29/2025
1.1.8 156 12/28/2025
1.1.6 150 12/28/2025
1.1.3 143 12/28/2025
1.0.3 148 12/28/2025
1.0.2 147 12/28/2025
1.0.1 284 9/22/2025