StageKit.Primitives 0.2.0

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

StageKit.Primitives

Logo

License GitHub repo size Code size Nuget GitHub Sponsors

StageKit.Primitives is a dependency-light .NET package with reusable low-level helpers used by StageKit libraries and available for other libraries or apps.

All public helpers are exposed from the StageKit.Primitives namespace. IO-related source files are grouped under an IO/ folder for organization only.

Features

  • Atomic file writes with temporary-file replacement through SafeFile
  • Stream-based atomic file writes through SafeFileStream
  • Path, temporary file, and temporary directory helpers
  • Disposable base type with thread-safe idempotent disposal through DisposableObject
  • Leave-open lifecycle base type through LeaveOpenDisposableObject
  • SafeHandle wrapper for pinned GCHandle scenarios through GCSafeHandle

Install

dotnet add package StageKit.Primitives

Requirements

  • .NET 8 or newer
  • C# latest language version

SafeFile

Use SafeFile when you need to write a file through a temporary file and then replace the destination.

using StageKit.Primitives;

SafeFile.WriteAllText("settings.json", json);

SafeFile.Write("settings.json", stream =>
{
    JsonSerializer.Serialize(stream, settings);
});

Async writes are supported:

await SafeFile.WriteAllTextAsync(
    "settings.json",
    json,
    cancellationToken: cancellationToken);

Temporary files use this pattern:

<destination>.tmp.<guid>

Use SafeFile.IsTemporaryPathFor(...) when filtering a directory that may contain temporary files for an in-progress write:

if (SafeFile.IsTemporaryPathFor(candidatePath, destinationPath))
{
    return;
}

SafeFileStream

Use SafeFileStream when you want stream-style writes with atomic replacement.

using StageKit.Primitives;
using System.Text;

using var stream = new SafeFileStream("settings.json");
stream.Write(Encoding.UTF8.GetBytes(json));
// Dispose commits by default.

Set commitOnDispose to false when you want to commit explicitly:

await using var stream = new SafeFileStream("settings.json", commitOnDispose: false);
await stream.WriteAsync(buffer, cancellationToken);
await stream.CommitAsync(cancellationToken);

If a SafeFileStream is disposed without committing and commitOnDispose is false, the temporary file is deleted and the destination is left unchanged.

IO Helpers

Use PathUtilities for platform-aware path comparisons and archive entry normalization:

if (!PathUtilities.IsSubPathOf(candidatePath, rootPath))
{
    throw new InvalidOperationException("Path escapes the root directory.");
}

var entryName = PathUtilities.NormalizeArchiveEntryName(relativePath);

Use TemporaryDirectory when a temporary workspace should be removed automatically:

using var directory = new TemporaryDirectory(prefix: "stagekit");
var outputPath = Path.Combine(directory.DirectoryPath, "output.json");

Use TemporaryFile when a temporary file should be removed unless explicitly kept:

using var file = new TemporaryFile(extension: "json");
await File.WriteAllTextAsync(file.FilePath, json);

file.Keep();

DisposableObject

Use DisposableObject for classes that need idempotent deterministic cleanup.

using StageKit.Primitives;

public sealed class Worker : DisposableObject
{
    private readonly Stream _stream;

    public Worker(Stream stream)
    {
        _stream = stream;
    }

    public void Run()
    {
        ThrowIfDisposed();

        // Use the stream.
    }

    protected override void DisposeManaged()
    {
        _stream.Dispose();
    }
}

DisposeManaged() runs for normal Dispose() calls. DisposeUnmanaged() always runs after managed cleanup is attempted, even if managed cleanup throws. The base class does not define a finalizer; types that directly own unmanaged resources should prefer SafeHandle or implement their own finalizer.

LeaveOpenDisposableObject

Use LeaveOpenDisposableObject when a type needs to expose a leave-open option for a resource owned by the caller.

using StageKit.Primitives;

public sealed class StreamWriterOwner : LeaveOpenDisposableObject
{
    private readonly Stream _stream;

    public StreamWriterOwner(Stream stream, bool leaveOpen)
        : base(leaveOpen)
    {
        _stream = stream;
    }

    protected override void DisposeManaged()
    {
        if (!LeaveOpen)
        {
            _stream.Dispose();
        }
    }
}

Derived classes are responsible for honoring LeaveOpen.

GCSafeHandle

GCSafeHandle wraps a GCHandle in a SafeHandle so pinned memory can be released reliably.

using StageKit.Primitives;

var buffer = new byte[1024];
using var handle = new GCSafeHandle(buffer);

IntPtr address = handle.DangerousGetHandle();

Use this only when pinning is necessary, such as interop paths that require a stable address. Keep pinning lifetimes short.

License

StageKit.Primitives is licensed under the MIT License.

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on StageKit.Primitives:

Package Downloads
EmguExtensions

A high-performance .NET library that extends Emgu.CV (OpenCV wrapper) with span-based Mat accessors, ROI utilities, pluggable Mat compression (PNG, Deflate, GZip, ZLib, Brotli, Zstd), CMat for memory-efficient compressed image storage, structured contour hierarchy wrappers, and drawing helpers for polygons and multi-line text rendering.

StageKit

StageKit is a lightweight .NET application infrastructure library for JSON settings, schema migrations, atomic storage, backups, support bundles, retention, onboarding state, single-instance guards, crash reports, and unhandled exception handling.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 143 5/27/2026