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/
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 |
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);
}
}
}| 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.
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.
Requires the .NET 10 SDK.
dotnet build Pineapple.slnx
dotnet test --solution Pineapple.slnx
dotnet pack Pineapple.slnx -c Release -o artifactsFastSearch · M5.BloomFilter · yocto · Polygon.Net · Cut & Move · MacEdgeLight
Issues and pull requests are welcome. See CHANGELOG.md for release history.
This project is licensed under the Apache License 2.0. © MILL5, LLC.
Created by Richard Crane — Microsoft MVP and founder of MILL5.
- MILL5: mill5.com
- Microsoft MVP profile: mvp.microsoft.com/…/Richard-Crane
- Podcast — Inventing Fire with AI: inventingfirewith.ai
- Support: rich@mill5.com
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
