---
title: 'C#'
description: "Paket NuGet JsonEvalRs menyediakan penghubung (binding) berperforma tinggi untuk aplikasi .NET. Paket ini membungkus core mesin Rust dengan API C# yang mudah digunakan dan aman (type-safe)."
navigation:
  icon: 'i-simple-icons-csharp'
seo:
  title: 'C#'
  description: "Paket NuGet JsonEvalRs menyediakan penghubung (binding) berperforma tinggi untuk aplikasi .NET. Paket ini membungkus core mesin Rust dengan API C# yang mudah digunakan dan aman (type-safe)."
---

## Instalasi

```bash
dotnet add package JsonEvalRs
```

Atau lewat NuGet Package Manager:
```bash
Install-Package JsonEvalRs
```

## Mulai Cepat

```csharp
using JsonEvalRs;
using Newtonsoft.Json.Linq;

// Tentukan schema dengan aturan validasi dan layout
string schema = @"{
    ""type"": ""object"",
    ""properties"": {
        ""email"": {
            ""type"": ""string"",
            ""rules"": {
                ""required"": { ""value"": true, ""message"": ""Email wajib diisi"" },
                ""pattern"": { 
                    ""value"": ""^[^@]+@[^@]+\\.[^@]+$"", 
                    ""message"": ""Format email tidak valid"" 
                }
            }
        }
    }
}";

// Gunakan blok 'using' untuk pembersihan otomatis
using (var eval = new JSONEval(schema))
{
    // 1. Evaluasi
    string data = @"{ ""email"": ""email-tidak-valid"" }";
    eval.Evaluate(data);

    // 2. Validasi
    ValidationResult validation = eval.Validate(data);
    
    if (validation.HasError)
    {
        foreach (var error in validation.Errors)
        {
            Console.WriteLine($"Kolom: {error.Path}, Error: {error.Message}");
        }
    }

    // 3. Ambil schema yang sudah dievaluasi (termasuk properti hasil hitungan)
    JObject result = eval.GetEvaluatedSchema();
}
```

## Referensi API

### Kelas `JSONEval`

Pintu utama untuk melakukan evaluasi. Mengimplementasikan `IDisposable` untuk mengelola sumber daya native.

#### Constructor

```csharp
public JSONEval(string schema, string? context = null, string? data = null)
```

-   **schema**: String definisi schema JSON.
-   **context**: Data konteks eksternal opsional (misal: info user, variabel lingkungan).
-   **data**: Data awal opsional.

#### `Evaluate`

Mengevaluasi schema terhadap data yang diberikan.

```csharp
public void Evaluate(string data, string? context = null, string[]? paths = null)
```

-   **data**: String data JSON.
-   **paths**: **[Baru]** Daftar jalur kolom opsional untuk [Evaluasi Selektif](selective-evaluation).

#### `EvaluateOnly`

Mengevaluasi status schema secara internal tanpa mengembalikan struktur JSON yang dihitung, memberikan opsi berkinerja tinggi saat Anda tidak segera membutuhkan dokumen akhir yang sudah diselesaikan.

```csharp
public void EvaluateOnly(string data, string? context = null, string[]? paths = null)
```

-   **data**: String data JSON.
-   **context**: Data konteks opsional.
-   **paths**: Daftar jalur kolom opsional.

#### `Validate`

Memvalidasi data terhadap aturan dalam schema.

```csharp
public ValidationResult Validate(string data, string? context = null)
```

Mengembalikan `ValidationResult` yang berisi:
-   `HasError` (bool)
-   `Errors` (Daftar `ValidationError`)

#### `EvaluateDependents`

Mengevaluasi ulang kolom yang bergantung pada perubahan tertentu secara efisien.

```csharp
public JArray EvaluateDependents(
    string[] changedPaths, 
    string? data = null, 
    string? context = null, 
    bool reEvaluate = false
)
```

-   **changedPaths**: Daftar jalur yang berubah (misal: `["user.email"]`).
-   **reEvaluate**: Jika true, akan menjalankan fungsi `Evaluate` penuh setelah menentukan ketergantungan.

#### Metode Lanjutan

**`ValidatePaths`**
Memvalidasi hanya jalur kolom tertentu di dalam data, bukan seluruh schema.
```csharp
public ValidationResult ValidatePaths(string data, string? context = null, List<string>? paths = null)
```

**`CompileLogic` & `RunLogic`**
Menyusun (compile) dan menjalankan ekspresi JSON Logic mandiri terpisah dari struktur schema penuh. Berguna untuk menjalankan logika yang terisolasi.
```csharp
public ulong CompileLogic(string logicStr)
public JToken RunLogic(ulong logicId, string? data = null, string? context = null)
public JToken CompileAndRunLogic(string logicStr, string? data = null, string? context = null)
```

**`SetTimezoneOffset`**
Memperbarui perbedaan waktu (timezone offset) untuk operator temporal (`today`, `now`, `dateformat`) saat evaluasi.
```csharp
public void SetTimezoneOffset(int? offsetMinutes) // misal: 420 untuk UTC+7
```

**`ResolveLayout`**
Menyelesaikan node layout UI (elemen `$layout`) secara terpisah dari siklus evaluasi utama.
```csharp
public void ResolveLayout(bool evaluate)
```

#### Pengambilan Data Schema

Metode-metode untuk mengambil status internal atau bagian dari schema setelah evaluasi.

**Ambil Schema Penuh**
```csharp
// Mengembalikan schema yang sudah dievaluasi sebagai JObject
public JObject GetEvaluatedSchema(bool skipLayout = false)

// Mengembalikan schema tanpa objek `$params`
public JObject GetEvaluatedSchemaWithoutParams(bool skipLayout = false)

// Mengembalikan schema sebagai bytes MessagePack untuk transfer data tanpa kopi (zero-copy)
public byte[] GetEvaluatedSchemaMsgpack(bool skipLayout = false)
```

**Ambil Jalur Spesifik**
Ambil bagian tertentu dari hasil evaluasi menggunakan jalur (misal: `#/properties/user`).
```csharp
public JToken GetEvaluatedSchemaByPath(string path, bool skipLayout = false)
public JObject GetEvaluatedSchemaByPaths(List<string> paths, bool skipLayout = false)
```

Ambil nilai tertentu dari struktur schema asli yang belum dievaluasi.
```csharp
public JToken GetSchemaByPath(string path)
public JObject GetSchemaByPaths(List<string> paths)
```

**Ambil Nilai Root**
Ambil hasil akhir `.value` dari kalkulasi root schema.
```csharp
public JToken GetSchemaValue()
public JArray GetSchemaValueArray()
public JObject GetSchemaValueObject()
```

#### Siklus Hidup & Caching

Mengelola masa aktif schema dan cache evaluasi internal.

**Memuat Ulang Schema**
Mengganti schema di dalam instance `JSONEval` yang sama tanpa perlu membuat objek baru.
```csharp
public void ReloadSchema(string schema, string? context = null, string? data = null)
public void ReloadSchemaMsgpack(byte[] schemaBytes, string? context = null, string? data = null)
public void ReloadSchemaFromCache(string cacheKey, string? context = null, string? data = null)
```

**Cache Schema Global**
Inisialisasi langsung dari schema yang sudah disusun dan disimpan di cache global.
```csharp
public static JSONEval FromCache(string cacheKey, string? context = null, string? data = null)
```

**Manajemen Cache Evaluasi**
Mengelola cache hasil evaluasi internal untuk instance saat ini.
```csharp
public void EnableCache()
public void DisableCache()
public void ClearCache()
public bool IsCacheEnabled()
public JObject GetCacheStats() // Mengembalikan { entri, hit, miss, hit_rate }
public int GetCacheLength()
```

**Manajemen Memori**
```csharp
public void Dispose()
```
Melepaskan memori Rust native yang dialokasikan untuk instance tersebut. Sangat disarankan untuk menggunakan blok `using` agar `Dispose()` terpanggil otomatis.

### Metode Subform

Untuk mengelola item array yang terisolasi (Subform).

#### `EvaluateSubform`

```csharp
public void EvaluateSubform(
    string subformPath, 
    string data, 
    string? context = null, 
    IEnumerable<string>? paths = null
)
```

-   **subformPath**: Referensi schema ke kolom array (misal: `#/line_items`).
-   **data**: Data untuk satu item yang sedang dievaluasi.
-   **paths**: Jalur opsional untuk evaluasi selektif di dalam subform.

#### `EvaluateDependentsSubform`

```csharp
public JArray EvaluateDependentsSubform(
    string subformPath, 
    string changedPath, 
    string? data = null, 
    string? context = null
)
```

## Dukungan Platform

-   **.NET Standard 2.0+**
-   **.NET 6/7/8+**
-   **Platform**: Windows (x64), Linux (x64), macOS (x64, ARM64)

## Performa & Koncurrency (Kebersamaan)

Library ini aman digunakan banyak thread untuk **akses baca**, tapi butuh akses eksklusif untuk operasi **tulis/evaluasi** pada instance yang sama. Untuk skenario server dengan trafik tinggi:

1.  **Baca Sekali, Pakai Berkali-kali**: Baca schema sekali dan buat instance `JSONEval` baru untuk setiap request menggunakan `JSONEval.FromCache`.
2.  **Dispose**: Selalu panggil `Dispose()` atau gunakan blok `using` untuk mencegah kebocoran memori (memory leak).

```csharp
// Inisialisasi global
var schemaKey = "schema_utama";
// Diasumsikan kamu sudah mem-pre-cache schemanya (penggunaan lanjutan)

// Tiap permintaan (request)
using (var eval = JSONEval.FromCache(schemaKey)) 
{
    eval.Evaluate(requestData);
}
```
