Pineapple 2.0.0

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

Pineapple — Guava-inspired core utilities for .NET

Compatibility APIs with platform replacements remain available through 2.x and report migration diagnostics. See the migration guide.

<img src="/_dp/https://raw.githubusercontent.com/MILL5/pineapple/main/pineapple.png" alt="Pineapple logo" width="96" align="right" />

NuGet NuGet CI License: Apache 2.0

Pineapple is an open-source C# library of core utilities for .NET 8, 9, 10, and 11 RC, 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: Pineapple guides · Project documentation

Install

dotnet add package Pineapple --version 2.0.0
dotnet add package Pineapple.Data --version 2.0.0   # optional: SQL Server / EF Core helpers

Pineapple and Pineapple.Data share version 2.0.0 and release together. Keep direct references to both packages on the same version.

Package Targets What's inside
Pineapple .NET 8, 9, 10, 11 RC Preconditions, ShortGuid, HashCode, RowVersion, Cleanup, threading, diagnostics, health checks, Brotli handler
Pineapple.Data .NET 8 (EF Core 8), .NET 9 (EF Core 9), .NET 10/11 (EF Core 10) EF Core model for INFORMATION_SCHEMA, SQL Server availability check

Quick start

using Pineapple.Common;
using Pineapple.Diagnostics;
using static Pineapple.Common.Preconditions;
using HashCode = Pineapple.Common.HashCode;

public sealed class OrderService(IOrderRepository repository, ILogger<OrderService> logger)
{
    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;

        // Same inputs and byte encoding yield the same hash across processes and restarts.
        var cacheKey = HashCode.Combine("order", id.Guid.ToString(), quantity);

        // Logs "Operation [LoadOrder] called from [GetAsync] took 12.34ms" at Debug level.
        using (new TimingScope("LoadOrder", logger))
        {
            return await repository.GetAsync(id.Guid, cacheKey);
        }
    }
}

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
Parallelism Parallelism Size Parallel.ForEach loops to the machine's CPUs
Diagnostics TimingScope, ConsoleColorScope Log how long an operation took with structured ILogger events
Async plumbing SynchronizationContextScope, SuppressSynchronizationContextScope Avoid sync-over-async deadlocks
Cleanup Cleanup.SafeMethod Run cleanup code that must never throw
Schema InformationSchemaContext Query SQL Server INFORMATION_SCHEMA with LINQ

See the documentation site for a guide to each area.

Deprecated in 2.0

.NET now ships built-in replacements for these, so they are marked [Obsolete] (diagnostics PINE001–PINE008) and will be removed in 3.0. The migration guide shows each replacement.

Deprecated Use instead
BrotliCompressionHandler AutomaticDecompression = DecompressionMethods.All
ResourceGoverner, RateLimiterScope, SafeRateLimiterScope, SemaphoreRateLimiterScope System.Threading.RateLimiting
AccurateTimeout, SimpleTimeout, ExponentialWait CancellationTokenSource, Task.WaitAsync, Polly retry
MeasureScope, CallsPerMinute System.Diagnostics.Metrics
Scavenger PeriodicTimer
Health.Check, Data.SqlClient.Check Microsoft.Extensions.Diagnostics.HealthChecks
ImmutableExtensions ImmutableList.Add / AddRange
ServiceCollectionExtensions TryAddSingleton

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, 9, 10, and 11 (release candidate). 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 and byte encoding give the same hash across application instances — 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 11 release-candidate SDK pinned in global.json, plus .NET 8, 9, and 10 runtimes for their tests. .NET 11 coverage uses a release candidate until GA.

dotnet build Pineapple.slnx
dotnet test --solution Pineapple.slnx
dotnet pack Pineapple.slnx -c Release -o artifacts
bash scripts/verify-packages.sh artifacts  # requires Python 3

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

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

NuGet packages (11)

Showing the top 5 NuGet packages that depend on Pineapple:

Package Downloads
Polygon.Net

A .NET class library for use against the Polygon APIs supporting .NET Standard, .NET Core, .NET 5.0, and the new .NET 6.0

Intrinio.Net

This is a port of the Intrinio.Net to .NET Standard so that it can be used across .NET Framework, .NET Core, .NET 6.0+.

FastSearch

Fast, low-memory, case-insensitive substring (contains) search over in-memory collections of objects. NGramSearch indexes 1M items in about 1 s with 47 MiB and answers typical queries in about 5 µs.

M5.BloomFilter

A Bloom filter for .NET 10 and .NET 11. Lock-free lookups, allocation-free string, numeric and span keys, sizing from an expected count and a false-positive target, occupancy estimates, union of compatible filters, immutable snapshots, and a versioned persisted format with JSON and protobuf companion packages.

M5Finance

M5Finance is an aggregation of as many free and public sources of financial data. This includes NASDAQ, NYSE, and NYSE American stock exchanges.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 120 11/3/2026
1.0.41 29,285 9/5/2022
1.0.40 698 9/4/2022
1.0.36 25,425 9/3/2021
1.0.35 3,805 8/26/2021
1.0.34 10,685 7/22/2021
1.0.33 663 7/22/2021
1.0.32-alpha 1,210 7/13/2021
1.0.31-alpha 540 7/12/2021
1.0.30 6,140 3/30/2021
1.0.30-alpha 529 7/12/2021
1.0.29-alpha 1,157 3/26/2021
1.0.28-alpha 472 3/26/2021
1.0.27-alpha 503 3/25/2021
1.0.26-alpha 623 3/21/2021
1.0.24-alpha 547 3/17/2021
1.0.23-alpha 530 3/17/2021
1.0.22-alpha 546 3/16/2021
1.0.20-alpha 541 3/12/2021
1.0.19-alpha 608 3/7/2021
Loading failed

2.0.0: Targets .NET 8, 9, 10, and 11 RC; retains K4os xxHash and persisted results. Modernizes supported utilities and dependencies; legacy APIs with platform replacements remain available through 2.x with PINE001-PINE008 migration diagnostics. See https://github.com/MILL5/pineapple/blob/main/CHANGELOG.md