SnowBank.Core 7.4.2

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

SnowBank SDK - Core Library

The foundation library of the SnowBank SDK and the FoundationDB .NET client. It provides the high-performance, allocation-conscious building blocks that every other package in the SDK is built on, and that any application consuming the SDK will end up shipping.

SnowBank.Core has no dependency on FoundationDB (or on any database): it is a general-purpose toolkit that can be used entirely on its own.

What's inside

Slice, SliceReader and SliceWriter

Slice is a readonly struct, a better ReadOnlyMemory<byte> purpose-built for binary data, with a large set of encoders and decoders. SliceWriter builds a buffer, SliceReader walks one back, and SliceOwner lets a Slice own a pooled backing array so hot paths stay allocation-light.

// simple encoders and decoders on Slice itself
Slice hello = Slice.FromStringUtf8("hello");
string text = hello.ToStringUtf8();      // "hello"
Slice number = Slice.FromInt32(12345);   // also fixed-width, hex, base64, GUIDs, ...

// build a buffer with SliceWriter
var writer = new SliceWriter(64);
writer.WriteFixed32(0xDEADBEEF);         // 4 bytes, little-endian (WriteFixed32BE for big-endian)
writer.WriteVarInt32(12345);             // variable-length integer
writer.WriteStringUtf8("hello");
Slice buffer = writer.ToSlice();

// walk it back with SliceReader, in the same order
var reader = new SliceReader(buffer);
uint magic = reader.ReadFixed32();
Slice rest = reader.ReadToEnd();

For hot paths, rent the writer's backing array from a pool and hand the result off as a SliceOwner:

var writer = new SliceWriter(ArrayPool<byte>.Shared);
writer.WriteStringUtf8("...");

SliceOwner owner = writer.ToSliceOwner();  // ownership of the pooled buffer moves to the owner
Consume(owner.Data);                       // owner.Data is the resulting Slice
owner.Dispose();                           // returns the buffer to the pool

Tuples

An implementation of tuples close to FoundationDB's Python layer: a compact, order-preserving binary encoding for composite values. TuPack packs a set of values into a Slice and unpacks it back, keeping both type and sort order.

Slice packed = TuPack.EncodeKey("users", 42, "email");

var t = TuPack.Unpack(packed);
string first = t.Get<string>(0);     // "users"
int second   = t.Get<int>(1);        // 42

This is ideal for values, and for any non-FoundationDB use of an ordered composite encoding. Note that a FoundationDB key is not just a raw packed tuple: keys are built relative to a Directory subspace (which supplies a location prefix) using the key encoders in FoundationDB.Client. Packing a raw tuple with TuPack.EncodeKey and using it directly as a key skips that prefix, and is unsafe. See the FoundationDB.Client package for how to build keys correctly.

CrystalJson, a fast JSON stack

A supercharged JSON implementation: a JsonValue DOM (JsonObject, JsonArray, ...) with a read-only vs. mutable model, a parser and binder, and a Roslyn source generator that emits reflection-free serializers and read-only/writable proxies for hot paths.

// serialize any object
string json = CrystalJson.Serialize(new { name = "Java Depp", beans = 81 });

// parse into a queryable DOM
JsonValue doc = CrystalJson.Parse(json);
int beans = doc["beans"].ToInt32();

// or deserialize straight into a type
var obj = CrystalJson.Deserialize<MyRecord>(json);

For the fast path, declare a partial container that lists the types you want generated, and the source generator produces reflection-free serializers plus typed read-only and writable proxies over a JsonObject:

[CrystalJsonConverter]
[CrystalJsonSerializable(typeof(Person))]
public static partial class GeneratedConverters { }

public sealed record Person
{
    public required string FirstName { get; init; }
    public required string FamilyName { get; init; }
}

var person = new Person { FirstName = "James", FamilyName = "Bond" };

// a read-only proxy: typed access over an immutable JsonObject, no reflection
var ro = GeneratedConverters.Person.ToReadOnly(person);
string first = ro.FirstName;                 // "James"

// a writable proxy: mutate fields, then read the JSON or decode back to a Person
var w = GeneratedConverters.Person.ToMutable(person);
w.FirstName = "Jim";
JsonValue json = w.ToJsonValue();            // { "firstName": "Jim", "familyName": "Bond" }
Person updated = w.ToValue();

UUIDs and compact identifiers

Uuid128 (and its Uuid96, Uuid80, Uuid64 siblings) are value types for compact, sortable identifiers, with encoders and decoders that match the rest of the SDK (Slice, spans, SliceWriter).

Uuid128 id = Uuid128.NewUuid();          // random (version 4)

// text round-trip
string s = id.ToString();
Uuid128 back = Uuid128.Parse(s);

// binary (16 bytes): to a Slice, a caller-owned span, or a SliceWriter
Slice slice = id.ToSlice();
Span<byte> buf = stackalloc byte[16];
id.WriteTo(buf);
Uuid128 fromSpan = Uuid128.Read(buf);    // also Read(Slice) / Read(byte[])

// compose from, and split into, fixed-size chunks
Uuid128 composed = Uuid128.FromUpper64Lower64(hi: 0x0123456789ABCDEFUL, low: 0xFEDCBA9876543210UL);
var (high, low) = composed;              // two 64-bit halves (Uuid64)
var (a, b, c, d) = composed;             // four 32-bit chunks

Contracts, lightweight guards

Contract provides concise argument and state guards. They throw the right exception with the parameter name filled in automatically (via CallerArgumentExpression).

public void Send(string channel, ReadOnlySpan<byte> payload, int offset, int count)
{
    Contract.NotNullOrEmpty(channel);                        // ArgumentException if null or empty
    Contract.Positive(count);                                // must be > 0
    Contract.GreaterThan(offset, -1);                        // must be > -1
    Contract.DoesNotOverflow(payload.Length, offset, count); // offset + count must fit the buffer
    // ...
}

NotNull, NotNullOrEmpty, NotNullOrWhiteSpace, Positive, GreaterThan / GreaterOrEqual / LessThan, Between, and DoesNotOverflow cover the common cases.

For invariants that should only be checked in debug builds (and compiled out of Release), use Contract.Debug:

Contract.Debug.Requires(offset >= 0);                    // precondition, checked in DEBUG only
// ...
Contract.Debug.Ensures(this.Position <= this.Length);    // postcondition

And more

  • Collections: cache-oblivious ordered stores and other specialized collections.
  • Hashing: fast non-cryptographic hashing (XxHash).
  • Runtime helpers: type converters, and shared interfaces implemented by the higher-level packages.

Bridging a migration from .NET Framework (netstandard2.0)

Besides net8.0 / net10.0 / net11.0, SnowBank.Core also multi-targets netstandard2.0. This is not about running new code on .NET Framework as an end goal. It exists to smooth the migration of a large legacy application to modern .NET.

Porting a big codebase is almost never a single commit. In practice the legacy branch (still on .NET Framework 4.7.2) and the modernized branch (targeting, say, .NET 10) have to coexist for a while: the team keeps shipping fixes and features from the old branch while the new one is brought up, and those changes have to be continuously merged across.

That merge is where the cost is, and where the netstandard2.0 build helps. Because the legacy branch can reference SnowBank.Core too, the modern APIs it provides (Slice, CrystalJson, the Tuple encoding, Contract.NotNull, ...) compile and run on .NET Framework as well. So the code that uses them reads identically on both branches, which sharply cuts merge conflicts, and lets you backport the C# modernization (newer language features, the modern API shapes) onto the old branch incrementally, instead of maintaining two divergent styles until the very end.

The encodings are byte-identical across all targets (a Slice, a packed tuple, or a JSON document produced on netstandard2.0 matches the one produced on net10.0), so data written by either branch stays interchangeable throughout the transition. Once the migration lands and the legacy branch is retired, the netstandard2.0 target can simply be dropped.

Part of a larger SDK

SnowBank.Core is the base of the whole family: FoundationDB.Client (the FoundationDB binding) and the CloudLayer layers (DocStore, Teleport, ...) are all built on top of it. See the repository for the full picture and the getting-started guide.

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 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 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 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.  net11.0 is compatible. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  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 (3)

Showing the top 3 NuGet packages that depend on SnowBank.Core:

Package Downloads
FoundationDB.Client

This is the FoundationDB client library for developing .NET applications or layers.

SnowBank.Networking.Http

Core HTTP SDK for writing distributed .NET applications

SnowBank.Testing.Common

Library for writing NUnit tests with the SnowBank SDK

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
7.4.2 52 7/13/2026
7.4.1 117 7/5/2026
7.4.0 140 5/1/2026
7.3.2 2,624 6/13/2025
7.3.1 1,446 5/30/2025