diff --git a/TriasDev.Templify.Tests/ConditionEvaluatorTests.cs b/TriasDev.Templify.Tests/ConditionEvaluatorTests.cs
new file mode 100644
index 0000000..9e0a574
--- /dev/null
+++ b/TriasDev.Templify.Tests/ConditionEvaluatorTests.cs
@@ -0,0 +1,349 @@
+// Copyright (c) 2025 TriasDev GmbH & Co. KG
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+
+using System.Text.Json;
+using TriasDev.Templify.Conditionals;
+using TriasDev.Templify.Core;
+
+namespace TriasDev.Templify.Tests;
+
+///
+/// Tests for the public class.
+///
+public class ConditionEvaluatorTests
+{
+ private readonly ConditionEvaluator _evaluator = new();
+
+ #region Evaluate with Dictionary
+
+ [Fact]
+ public void Evaluate_WithTrueBoolean_ReturnsTrue()
+ {
+ Dictionary data = new() { ["IsActive"] = true };
+
+ bool result = _evaluator.Evaluate("IsActive", data);
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void Evaluate_WithFalseBoolean_ReturnsFalse()
+ {
+ Dictionary data = new() { ["IsActive"] = false };
+
+ bool result = _evaluator.Evaluate("IsActive", data);
+
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void Evaluate_WithMissingVariable_ReturnsFalse()
+ {
+ Dictionary data = new();
+
+ bool result = _evaluator.Evaluate("MissingVar", data);
+
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void Evaluate_WithComparison_ReturnsCorrectResult()
+ {
+ Dictionary data = new() { ["Count"] = 5 };
+
+ Assert.True(_evaluator.Evaluate("Count > 3", data));
+ Assert.True(_evaluator.Evaluate("Count = 5", data));
+ Assert.False(_evaluator.Evaluate("Count < 3", data));
+ }
+
+ [Fact]
+ public void Evaluate_WithStringComparison_ReturnsCorrectResult()
+ {
+ Dictionary data = new() { ["Status"] = "Active" };
+
+ bool result = _evaluator.Evaluate("Status = \"Active\"", data);
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void Evaluate_WithLogicalOperators_ReturnsCorrectResult()
+ {
+ Dictionary data = new()
+ {
+ ["IsEnabled"] = true,
+ ["HasAccess"] = true
+ };
+
+ Assert.True(_evaluator.Evaluate("IsEnabled and HasAccess", data));
+ Assert.True(_evaluator.Evaluate("IsEnabled or HasAccess", data));
+ }
+
+ [Fact]
+ public void Evaluate_WithNegation_ReturnsCorrectResult()
+ {
+ Dictionary data = new() { ["IsDisabled"] = false };
+
+ bool result = _evaluator.Evaluate("not IsDisabled", data);
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void Evaluate_WithNestedPath_ReturnsCorrectResult()
+ {
+ Dictionary data = new()
+ {
+ ["Customer"] = new Dictionary
+ {
+ ["Name"] = "John",
+ ["IsActive"] = true
+ }
+ };
+
+ Assert.True(_evaluator.Evaluate("Customer.IsActive", data));
+ Assert.True(_evaluator.Evaluate("Customer.Name = \"John\"", data));
+ }
+
+ #endregion
+
+ #region Evaluate with JSON
+
+ [Fact]
+ public void Evaluate_WithJsonData_ReturnsCorrectResult()
+ {
+ string json = """{"IsActive": true, "Count": 5}""";
+
+ Assert.True(_evaluator.Evaluate("IsActive", json));
+ Assert.True(_evaluator.Evaluate("Count > 3", json));
+ }
+
+ [Fact]
+ public void Evaluate_WithComplexJsonData_ReturnsCorrectResult()
+ {
+ string json = """
+ {
+ "Customer": {
+ "Name": "John",
+ "IsActive": true
+ },
+ "Status": "Active"
+ }
+ """;
+
+ Assert.True(_evaluator.Evaluate("Customer.IsActive", json));
+ Assert.True(_evaluator.Evaluate("Status = \"Active\"", json));
+ }
+
+ [Fact]
+ public void Evaluate_WithInvalidJson_ThrowsJsonException()
+ {
+ string invalidJson = "{ invalid json }";
+
+ Assert.Throws(() => _evaluator.Evaluate("IsActive", invalidJson));
+ }
+
+ [Fact]
+ public void Evaluate_WithJsonArray_ThrowsJsonException()
+ {
+ string jsonArray = "[1, 2, 3]";
+
+ Assert.Throws(() => _evaluator.Evaluate("IsActive", jsonArray));
+ }
+
+ #endregion
+
+ #region EvaluateAsync
+
+ [Fact]
+ public async Task EvaluateAsync_WithDictionary_ReturnsCorrectResult()
+ {
+ Dictionary data = new() { ["IsActive"] = true };
+
+ bool result = await _evaluator.EvaluateAsync("IsActive", data);
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public async Task EvaluateAsync_WithJson_ReturnsCorrectResult()
+ {
+ string json = """{"IsActive": true}""";
+
+ bool result = await _evaluator.EvaluateAsync("IsActive", json);
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public async Task EvaluateAsync_WithContext_ReturnsCorrectResult()
+ {
+ Dictionary data = new() { ["IsActive"] = true };
+ IEvaluationContext context = _evaluator.CreateContext(data);
+
+ bool result = await _evaluator.EvaluateAsync("IsActive", context);
+
+ Assert.True(result);
+ }
+
+ #endregion
+
+ #region CreateContext
+
+ [Fact]
+ public void CreateContext_WithDictionary_ReturnsValidContext()
+ {
+ Dictionary data = new()
+ {
+ ["Name"] = "Test",
+ ["Count"] = 42
+ };
+
+ IEvaluationContext context = _evaluator.CreateContext(data);
+
+ Assert.NotNull(context);
+ Assert.True(context.TryResolveVariable("Name", out object? name));
+ Assert.Equal("Test", name);
+ Assert.True(context.TryResolveVariable("Count", out object? count));
+ Assert.Equal(42, count);
+ }
+
+ [Fact]
+ public void CreateContext_WithJson_ReturnsValidContext()
+ {
+ string json = """{"Name": "Test", "Count": 42}""";
+
+ IEvaluationContext context = _evaluator.CreateContext(json);
+
+ Assert.NotNull(context);
+ Assert.True(context.TryResolveVariable("Name", out object? name));
+ Assert.Equal("Test", name);
+ }
+
+ [Fact]
+ public void CreateContext_AllowsBatchEvaluation()
+ {
+ Dictionary data = new()
+ {
+ ["IsActive"] = true,
+ ["Count"] = 5,
+ ["Status"] = "Active"
+ };
+
+ IEvaluationContext context = _evaluator.CreateContext(data);
+
+ Assert.True(_evaluator.Evaluate("IsActive", context));
+ Assert.True(_evaluator.Evaluate("Count > 3", context));
+ Assert.True(_evaluator.Evaluate("Status = \"Active\"", context));
+ }
+
+ #endregion
+
+ #region Evaluate with Context
+
+ [Fact]
+ public void Evaluate_WithContext_ReturnsCorrectResult()
+ {
+ Dictionary data = new()
+ {
+ ["IsEnabled"] = true,
+ ["Count"] = 10
+ };
+ IEvaluationContext context = _evaluator.CreateContext(data);
+
+ Assert.True(_evaluator.Evaluate("IsEnabled", context));
+ Assert.True(_evaluator.Evaluate("Count > 5", context));
+ Assert.True(_evaluator.Evaluate("IsEnabled and Count > 5", context));
+ }
+
+ #endregion
+
+ #region Interface Implementation
+
+ [Fact]
+ public void ConditionEvaluator_ImplementsIConditionEvaluator()
+ {
+ IConditionEvaluator evaluator = new ConditionEvaluator();
+
+ Assert.NotNull(evaluator);
+ }
+
+ #endregion
+
+ #region Null Parameter Validation
+
+ [Fact]
+ public void Evaluate_WithNullExpression_ThrowsArgumentNullException()
+ {
+ Dictionary data = new() { ["Key"] = "Value" };
+
+ Assert.Throws(() => _evaluator.Evaluate(null!, data));
+ }
+
+ [Fact]
+ public void Evaluate_WithNullDictionary_ThrowsArgumentNullException()
+ {
+ Assert.Throws(() => _evaluator.Evaluate("IsActive", (Dictionary)null!));
+ }
+
+ [Fact]
+ public void Evaluate_WithNullJsonData_ThrowsArgumentNullException()
+ {
+ Assert.Throws(() => _evaluator.Evaluate("IsActive", (string)null!));
+ }
+
+ [Fact]
+ public void Evaluate_WithNullContext_ThrowsArgumentNullException()
+ {
+ Assert.Throws(() => _evaluator.Evaluate("IsActive", (IEvaluationContext)null!));
+ }
+
+ [Fact]
+ public void CreateContext_WithNullDictionary_ThrowsArgumentNullException()
+ {
+ Assert.Throws(() => _evaluator.CreateContext((Dictionary)null!));
+ }
+
+ [Fact]
+ public void CreateContext_WithNullJsonData_ThrowsArgumentNullException()
+ {
+ Assert.Throws(() => _evaluator.CreateContext((string)null!));
+ }
+
+ [Fact]
+ public async Task EvaluateAsync_WithNullExpression_ThrowsArgumentNullException()
+ {
+ Dictionary data = new() { ["Key"] = "Value" };
+
+ await Assert.ThrowsAsync(() => _evaluator.EvaluateAsync(null!, data));
+ }
+
+ [Fact]
+ public async Task EvaluateAsync_WithNullDictionary_ThrowsArgumentNullException()
+ {
+ await Assert.ThrowsAsync(() => _evaluator.EvaluateAsync("IsActive", (Dictionary)null!));
+ }
+
+ [Fact]
+ public async Task EvaluateAsync_WithNullJsonData_ThrowsArgumentNullException()
+ {
+ await Assert.ThrowsAsync(() => _evaluator.EvaluateAsync("IsActive", (string)null!));
+ }
+
+ [Fact]
+ public async Task EvaluateAsync_WithNullContext_ThrowsArgumentNullException()
+ {
+ await Assert.ThrowsAsync(() => _evaluator.EvaluateAsync("IsActive", (IEvaluationContext)null!));
+ }
+
+ [Fact]
+ public async Task EvaluateAsync_WithCancelledToken_ThrowsOperationCanceledException()
+ {
+ Dictionary data = new() { ["IsActive"] = true };
+ CancellationToken cancelledToken = new(canceled: true);
+
+ await Assert.ThrowsAsync(() => _evaluator.EvaluateAsync("IsActive", data, cancelledToken));
+ }
+
+ #endregion
+}
diff --git a/TriasDev.Templify/Conditionals/ConditionEvaluator.cs b/TriasDev.Templify/Conditionals/ConditionEvaluator.cs
new file mode 100644
index 0000000..5f251a0
--- /dev/null
+++ b/TriasDev.Templify/Conditionals/ConditionEvaluator.cs
@@ -0,0 +1,124 @@
+// Copyright (c) 2025 TriasDev GmbH & Co. KG
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+
+using TriasDev.Templify.Core;
+using TriasDev.Templify.Utilities;
+
+namespace TriasDev.Templify.Conditionals;
+
+///
+/// Provides standalone condition evaluation functionality.
+///
+///
+///
+/// This class exposes the condition evaluation engine used by Templify templates
+/// for use in standalone scenarios without Word document processing.
+///
+///
+/// Thread Safety: This class is thread-safe. The underlying evaluator has no mutable
+/// instance state (only immutable constants), so multiple threads can call Evaluate
+/// concurrently without synchronization.
+///
+///
+///
+/// Basic usage:
+///
+/// var evaluator = new ConditionEvaluator();
+/// var data = new Dictionary<string, object>
+/// {
+/// ["IsActive"] = true,
+/// ["Count"] = 5,
+/// ["Status"] = "Active"
+/// };
+///
+/// bool result1 = evaluator.Evaluate("IsActive", data); // true
+/// bool result2 = evaluator.Evaluate("Count > 3", data); // true
+/// bool result3 = evaluator.Evaluate("Status = \"Active\"", data); // true
+///
+///
+///
+/// Using JSON data:
+///
+/// var evaluator = new ConditionEvaluator();
+/// string json = """{"IsActive": true, "Count": 5}""";
+///
+/// bool result = evaluator.Evaluate("IsActive and Count > 0", json);
+///
+///
+///
+/// Batch evaluation with context:
+///
+/// var evaluator = new ConditionEvaluator();
+/// var context = evaluator.CreateContext(data);
+///
+/// // Evaluate multiple expressions efficiently
+/// bool r1 = evaluator.Evaluate("Condition1", context);
+/// bool r2 = evaluator.Evaluate("Condition2", context);
+/// bool r3 = evaluator.Evaluate("Condition3", context);
+///
+///
+public sealed class ConditionEvaluator : IConditionEvaluator
+{
+ private readonly ConditionalEvaluator _evaluator = new();
+
+ ///
+ public bool Evaluate(string expression, Dictionary data)
+ {
+ ArgumentNullException.ThrowIfNull(expression);
+ ArgumentNullException.ThrowIfNull(data);
+ return _evaluator.Evaluate(expression, data);
+ }
+
+ ///
+ public bool Evaluate(string expression, string jsonData)
+ {
+ ArgumentNullException.ThrowIfNull(expression);
+ ArgumentNullException.ThrowIfNull(jsonData);
+ Dictionary data = JsonDataParser.ParseJsonToDataDictionary(jsonData);
+ return _evaluator.Evaluate(expression, data);
+ }
+
+ ///
+ public bool Evaluate(string expression, IEvaluationContext context)
+ {
+ ArgumentNullException.ThrowIfNull(expression);
+ ArgumentNullException.ThrowIfNull(context);
+ return _evaluator.Evaluate(expression, context);
+ }
+
+ ///
+ public Task EvaluateAsync(string expression, Dictionary data, CancellationToken cancellationToken = default)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+ return Task.FromResult(Evaluate(expression, data));
+ }
+
+ ///
+ public Task EvaluateAsync(string expression, string jsonData, CancellationToken cancellationToken = default)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+ return Task.FromResult(Evaluate(expression, jsonData));
+ }
+
+ ///
+ public Task EvaluateAsync(string expression, IEvaluationContext context, CancellationToken cancellationToken = default)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+ return Task.FromResult(Evaluate(expression, context));
+ }
+
+ ///
+ public IEvaluationContext CreateContext(Dictionary data)
+ {
+ ArgumentNullException.ThrowIfNull(data);
+ return new GlobalEvaluationContext(data);
+ }
+
+ ///
+ public IEvaluationContext CreateContext(string jsonData)
+ {
+ ArgumentNullException.ThrowIfNull(jsonData);
+ Dictionary data = JsonDataParser.ParseJsonToDataDictionary(jsonData);
+ return new GlobalEvaluationContext(data);
+ }
+}
diff --git a/TriasDev.Templify/Conditionals/IConditionEvaluator.cs b/TriasDev.Templify/Conditionals/IConditionEvaluator.cs
new file mode 100644
index 0000000..696971e
--- /dev/null
+++ b/TriasDev.Templify/Conditionals/IConditionEvaluator.cs
@@ -0,0 +1,144 @@
+// Copyright (c) 2025 TriasDev GmbH & Co. KG
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+
+using TriasDev.Templify.Core;
+
+namespace TriasDev.Templify.Conditionals;
+
+///
+/// Provides standalone condition evaluation functionality.
+///
+///
+///
+/// This interface exposes the condition evaluation engine used by Templify templates
+/// for use in standalone scenarios without Word document processing.
+///
+///
+/// Supported operators: =, !=, >, <, >=, <=, and, or, not
+///
+///
+/// Examples:
+///
+/// var evaluator = new ConditionEvaluator();
+///
+/// // Simple variable check
+/// evaluator.Evaluate("IsActive", data); // true if IsActive is truthy
+///
+/// // Comparison
+/// evaluator.Evaluate("Status = \"Active\"", data);
+///
+/// // Complex expression
+/// evaluator.Evaluate("Count > 0 and IsEnabled", data);
+///
+///
+///
+public interface IConditionEvaluator
+{
+ #region Evaluate (Synchronous)
+
+ ///
+ /// Evaluates a conditional expression against the provided data.
+ ///
+ ///
+ /// The expression to evaluate. Supports:
+ ///
+ /// - Simple variables: "IsActive"
+ /// - Nested paths: "Customer.Address.City"
+ /// - Comparisons: "Status = \"Active\"", "Count > 0"
+ /// - Logical operators: "IsEnabled and HasAccess", "A or B"
+ /// - Negation: "not IsDisabled"
+ ///
+ ///
+ /// The data dictionary containing variables to resolve.
+ /// True if the condition is met; otherwise, false.
+ /// Thrown when or is null.
+ bool Evaluate(string expression, Dictionary data);
+
+ ///
+ /// Evaluates a conditional expression against JSON data.
+ ///
+ /// The expression to evaluate.
+ /// A JSON string representing the data object.
+ /// True if the condition is met; otherwise, false.
+ /// Thrown when or is null.
+ /// Thrown when JSON is invalid or root is not an object.
+ bool Evaluate(string expression, string jsonData);
+
+ ///
+ /// Evaluates a conditional expression using a pre-created evaluation context.
+ ///
+ /// The expression to evaluate.
+ /// The evaluation context containing variable data.
+ /// True if the condition is met; otherwise, false.
+ ///
+ /// Use this overload with a context from
+ /// for optimal performance when evaluating multiple expressions against the same data.
+ ///
+ /// Thrown when or is null.
+ bool Evaluate(string expression, IEvaluationContext context);
+
+ #endregion
+
+ #region EvaluateAsync (Asynchronous)
+
+ ///
+ /// Asynchronously evaluates a conditional expression against the provided data.
+ ///
+ /// The expression to evaluate.
+ /// The data dictionary containing variables to resolve.
+ /// A token to cancel the operation.
+ /// A task that resolves to true if the condition is met; otherwise, false.
+ /// Thrown when or is null.
+ /// Thrown when the operation is canceled.
+ Task EvaluateAsync(string expression, Dictionary data, CancellationToken cancellationToken = default);
+
+ ///
+ /// Asynchronously evaluates a conditional expression against JSON data.
+ ///
+ /// The expression to evaluate.
+ /// A JSON string representing the data object.
+ /// A token to cancel the operation.
+ /// A task that resolves to true if the condition is met; otherwise, false.
+ /// Thrown when or is null.
+ /// Thrown when JSON is invalid or root is not an object.
+ /// Thrown when the operation is canceled.
+ Task EvaluateAsync(string expression, string jsonData, CancellationToken cancellationToken = default);
+
+ ///
+ /// Asynchronously evaluates a conditional expression using a pre-created evaluation context.
+ ///
+ /// The expression to evaluate.
+ /// The evaluation context containing variable data.
+ /// A token to cancel the operation.
+ /// A task that resolves to true if the condition is met; otherwise, false.
+ /// Thrown when or is null.
+ /// Thrown when the operation is canceled.
+ Task EvaluateAsync(string expression, IEvaluationContext context, CancellationToken cancellationToken = default);
+
+ #endregion
+
+ #region CreateContext
+
+ ///
+ /// Creates an evaluation context from a data dictionary for batch evaluations.
+ ///
+ /// The data dictionary containing variables to resolve.
+ /// An evaluation context that can be reused for multiple evaluations.
+ ///
+ /// Use this method when evaluating multiple expressions against the same data
+ /// to avoid repeated context creation overhead.
+ ///
+ /// Thrown when is null.
+ IEvaluationContext CreateContext(Dictionary data);
+
+ ///
+ /// Creates an evaluation context from JSON data for batch evaluations.
+ ///
+ /// A JSON string representing the data object.
+ /// An evaluation context that can be reused for multiple evaluations.
+ /// Thrown when is null.
+ /// Thrown when JSON is invalid or root is not an object.
+ IEvaluationContext CreateContext(string jsonData);
+
+ #endregion
+}