MidManStudio.Mdix 1.0.0

dotnet add package MidManStudio.Mdix --version 1.0.0
                    
NuGet\Install-Package MidManStudio.Mdix -Version 1.0.0
                    
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="MidManStudio.Mdix" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MidManStudio.Mdix" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="MidManStudio.Mdix" />
                    
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 MidManStudio.Mdix --version 1.0.0
                    
#r "nuget: MidManStudio.Mdix, 1.0.0"
                    
#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 MidManStudio.Mdix@1.0.0
                    
#: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=MidManStudio.Mdix&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=MidManStudio.Mdix&version=1.0.0
                    
Install as a Cake Tool

MidManStudio.Mdix

.NET runtime for DixScript (.mdix) — MidManStudio. Thin, safe P/Invoke bindings over the native dixscript Rust core (via mdix-ffi), plus a reflection-based POCO serializer, LINQ-style querying, AST-level merging, and native file-watch hot reload on top.

Targets netstandard2.1 — works from .NET Framework 4.7.2+, .NET Core 3.0+, .NET 5+, and Unity (2021 LTS+, IL2CPP and Mono).

Installation

dotnet add package MidManStudio.Mdix

Quick start

using MidManStudio.Mdix.Core;

// Load and read
var dbResult = Dix.LoadStr("@DATA( port = 8080, host = \"localhost\" )");
if (dbResult.IsFailure)
{
    Console.WriteLine(dbResult.Error.Message);
    return;
}

using var db = dbResult.SuccessResult;
var port = db.GetInt("port").SuccessResult;      // 8080
var host = db.GetString("host").SuccessResult;   // "localhost"

// Or from disk
using var fromDisk = Dix.Load("config.mdix").SuccessResult;

MdixResult<T> never throws for expected failure paths (missing key, type mismatch, bad file) — check IsSuccess/IsFailure and read SuccessResult/Error explicitly. Exceptions are reserved for programmer errors (null handle after Dispose, cyclic object graphs in the serializer, and similar).

Builder — construct a database programmatically

using var builder = MdixBuilder.Create()
    .Config(c => c.WithVersion("1.0.0"))
    .Enums(e => e.WithEnum("LogLevel", "DEBUG", "INFO", "WARN", "ERROR"))
    .Data(d => d
        .WithString("app_name", "MyGame")
        .WithInt("port", 8080)
        .WithEnum("log_level", "LogLevel", "INFO")
        .WithTableProperties("server", t => t
            .WithString("host", "localhost")
            .WithInt("port", 8080)));

using var db = builder.ToDatabase().SuccessResult;

The two-tier ordering DixScript's grammar requires (flat properties before any grouped/table/array entries) is enforced by the builder itself — an out-of-order call fails fast rather than producing .mdix text that won't parse.

POCO serialization — value types and reference types

public enum Environment { DEV = 1, STAGING = 2, PROD = 3 }

public class ServerConfig
{
    public string Host { get; set; } = "";
    public int Port { get; set; }
    public long RequestId { get; set; }       // 64-bit, no truncation
    public int? MaxConnections { get; set; }  // nullable value types
    public Environment Env { get; set; }      // enum properties
    public MdixHexColor AccentColor { get; set; }
}

var config = db.Deserialize<ServerConfig>("server").SuccessResult;

using var builder = MdixBuilder.Create();
builder.Serialize(config, "server");        // MdixResult<Unit>
var mdixText = builder.Serialize().SuccessResult;  // MdixResult<string>

Enum-typed properties round-trip as real DixScript enum references (Environment.PROD, not a bare int or string) as long as the C# enum's type name matches the DixScript @ENUMS declaration name it corresponds to — see Enum code generation below for a way to guarantee that by construction. long, float, Nullable<T> of any supported type, and the five DixScript leaf value types (MdixHexColor, MdixBlob, MdixRegex, MdixDate, MdixTimestamp) are all supported on both records (reference types) and structs (value types), nested arbitrarily deep.

Enum code generation

Generate a real, type-safe C# enum for every DixScript enum declared in a file's @ENUMS section, instead of hand-writing one and hoping it stays in sync:

var generated = MdixEnumCodeGenerator.GenerateFromFile(
    "config.mdix",
    @namespace: "MyGame.Config",
    accessModifier: "public");

File.WriteAllText("Environment.g.cs", generated.SuccessResult);

Field values without an explicit = N in the source are left unassigned in the generated code on purpose — C#'s own enum auto-numbering rule (previous value + 1, starting at 0) is identical to DixScript's, so the C# compiler reproduces the same numbers DixScript would without this tool duplicating that arithmetic itself. The generated type name matches the DixScript enum name, which is exactly what MdixSerializer expects when writing an enum-typed property back out (see above).

MdixQuery — LINQ-style querying

var highPriority = db.QueryWhere<TaskItem>("tasks", t => t.Priority == 3)
                      .SuccessResult
                      .OrderByDescending(t => t.Priority);

var first = db.QueryFirst<TaskItem>("tasks", t => t.Priority == 3);
var count = db.QueryCount<TaskItem>("tasks");

QueryFirst, QueryLast, QuerySingle, QueryWhere, QuerySelect, QueryCount, QueryAny, QueryAll, QueryOrderBy/QueryOrderByDescending, QueryDistinct, QueryTake/QuerySkip all deserialize to a List<T> and hand you back a normal System.Linq-composable result — anything System.Linq itself offers (GroupBy, Sum, Average, ...) is already available on what these return.

Merge — full AST-level merging, not text concatenation

using var merged = MdixMerge.MergeSources(
    new[] { baseSource, overrideSource },
    strategy: MdixMergeStrategy.PrimaryWins,
    arrayStrategy: MdixArrayMergeStrategy.Concat).SuccessResult;

foreach (var conflict in merged.Conflicts)
    Console.WriteLine(conflict);  // "[Conflict] 'server.port' -> source[1] won"

Every value type (including the five DixScript leaf types and enums) survives a merge with full fidelity — this delegates straight into the native Rust merger rather than reimplementing conflict resolution in C#.

Hot reload

using var db = Dix.Load("config.mdix").SuccessResult;
db.OnReloaded     += newDb  => ApplyConfig(newDb);
db.OnReloadFailed += error  => Log.Warn(error.Message);
db.EnableHotReload();

Backed by System.IO.FileSystemWatcher (OS-level change notifications, not polling), with debounced reload handling for the double-fire behavior FileSystemWatcher is known for on most platforms. Call DisableHotReload() to stop watching.

Cross-platform native library

The native mdix_ffi library is bundled per-RID under runtimes/{rid}/native/ and resolved automatically on .NET Core 3.0+/.NET 5+; a build/-injected .targets file handles copy-to-output on .NET Framework and other older hosts. Check the specific package version's supported RID list if you're targeting something other than win-x64, linux-x64, or osx-arm64 — not every RID is necessarily built for every release.

Requirements

  • netstandard2.1-compatible target (.NET Framework 4.7.2+, .NET Core 3.0+, .NET 5+, Unity 2021 LTS+)
  • No Rust toolchain required — native binaries are pre-built and bundled
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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 was computed.  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 was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 89 8/4/2026