Skip to content
MILL5Public

About

MILL5's core libraries for .NET for developing quality software. Loosely based on Google's Guava libraries for Java.

Resources

Stars

3 stars

Watchers

2 watching

Forks

Repository files navigation

Pineapple — Guava-inspired core utilities for .NET

Pineapple logo

NuGet NuGet CI License: Apache 2.0

Pineapple is an open-source C# library of core utilities for .NET 8 and .NET 10, inspired by Google's Guava. It gives you guard clauses (preconditions), URL-safe 22-character ShortGuids, a deterministic xxHash HashCode, a SQL Server RowVersion type, calls-per-minute rate limiting and resource governors, timeouts, exponential backoff, timing scopes, and exception-safe cleanup helpers — small, dependency-light building blocks you would otherwise rewrite in every project.

📖 Documentation: https://mill5.github.io/pineapple/

Install

dotnet add package Pineapple
dotnet add package Pineapple.Data   # optional: SQL Server / EF Core helpers
Package Targets What's inside
Pineapple .NET 8, .NET 10 Preconditions, ShortGuid, HashCode, RowVersion, Cleanup, threading, diagnostics, health checks, Brotli handler
Pineapple.Data .NET 8 (EF Core 8), .NET 10 (EF Core 10) EF Core model for INFORMATION_SCHEMA, SQL Server availability check

Quick start

using Pineapple.Common;
using Pineapple.Threading;
using static Pineapple.Common.Preconditions;

public sealed class OrderService(IOrderRepository repository)
{
    // One governor per downstream dependency: at most 600 calls per minute.
    private static readonly ResourceGoverner Governor = new(maxCallsPerMinute: 600);

    public async Task<Order> GetAsync(string orderId, int quantity)
    {
        // Guard clauses throw ArgumentException-family exceptions with useful messages.
        CheckIsNotNullOrWhitespace(nameof(orderId), orderId);
        CheckIsNotLessThan(nameof(quantity), quantity, 1);

        // A ShortGuid is a Guid encoded as 22 URL-safe characters.
        ShortGuid id = orderId;

        await using (await Governor.GetOperationScopeAsync())
        {
            return await repository.GetAsync(id.Guid);
        }
    }
}

Features

Area Types Use it to
Guard clauses Preconditions Validate arguments: null/whitespace, ranges, dates, URIs, GUIDs, custom conditions
Identifiers ShortGuid, GuidExtensions Shorten GUIDs for URLs; sort GUIDs the way SQL Server does
Hashing HashCode Combine values into a hash that is stable across processes (xxHash32), unlike System.HashCode
Concurrency tokens RowVersion Compare, order, and convert SQL Server rowversion/timestamp values
Rate limiting RateLimiterScope, SafeRateLimiterScope, ResourceGoverner Cap calls per minute to an API or database
Timing & retry AccurateTimeout, SimpleTimeout, ExponentialWait, Parallelism Enforce deadlines, back off, size parallel loops
Diagnostics TimingScope, MeasureScope, ConsoleColorScope Log how long an operation took with ILogger
Async plumbing SynchronizationContextScope, SuppressSynchronizationContextScope Avoid sync-over-async deadlocks
Cleanup Cleanup.SafeMethod Run cleanup code that must never throw
Health Health.Check, Data.SqlClient.Check Probe TCP ports, URLs, processes, SQL Server
Networking BrotliCompressionHandler Decompress br responses in HttpClient pipelines
Schema InformationSchemaContext Query SQL Server INFORMATION_SCHEMA with LINQ

See the documentation site for a guide to each area.

FAQ

What is Pineapple? An Apache-2.0-licensed set of C# utility classes for .NET from MILL5, modeled on Google's Guava library for Java, with 110K+ NuGet downloads.

Which .NET versions are supported? .NET 8 (LTS) and .NET 10 (LTS). Version 1.x targeted .NET Standard 2.0; use Pineapple 1.0.41 if you still need .NET Framework.

How is Pineapple.Common.HashCode different from System.HashCode? System.HashCode is randomized per process. Pineapple's HashCode uses xxHash32, so the same inputs give the same hash on every machine and every run — useful for caching keys, sharding, and persisted hashes.

What is a ShortGuid? A 128-bit Guid encoded as 22 URL-safe Base64 characters (- and _ instead of + and /, no padding) — 14 characters shorter than the standard 36-character form, with implicit conversions to and from Guid and string.

More questions: FAQ.

Building from source

Requires the .NET 10 SDK.

dotnet build Pineapple.slnx
dotnet test --solution Pineapple.slnx
dotnet pack Pineapple.slnx -c Release -o artifacts

Part of the MILL5 open-source family

FastSearch · M5.BloomFilter · yocto · Polygon.Net · Cut & Move · MacEdgeLight

Contributing

Issues and pull requests are welcome. See CHANGELOG.md for release history.

License

This project is licensed under the Apache License 2.0. © MILL5, LLC.

Credits

Created by Richard Crane — Microsoft MVP and founder of MILL5.


Powered by MILL5 Explore Richard Crane on Microsoft MVP Listen to the Inventing Fire with AI podcast for insights on technology and innovation. For support, contact: rich@mill5.com

About

MILL5's core libraries for .NET for developing quality software. Loosely based on Google's Guava libraries for Java.

Resources

Stars

3 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages