The extension methods and utilities you rewrite in every project
Six independently-versioned packages sharing one centralized interface and model foundation — install only what a given project needs.
$ dotnet add package PowerCSharp.Core100+ extension methods across strings, collections, and dynamic LINQ
Strings (ToTitleCase, ToCamelCase, IsValidUrl), collections (IsNullOrEmpty, Page, RemoveAll), DateTime (GetAge, IsWeekend), dynamic LINQ query building, and JSON/XML helpers — the bulk of the day-to-day surface area.
using PowerCSharp.Extensions;
string text = "hello world";
bool isEmpty = text.IsNullOrWhiteSpace(); // false
string title = text.ToTitleCase(); // "Hello World"
string safe = text.SafeSubstring(0, 5); // "hello"Path traversal handled by default, not by convention
PathExtensions.CombineAndValidate canonicalizes user-supplied path segments and throws a SecurityException if the resolved path escapes the base directory — a concrete CWE-73 remediation, not a documentation warning.
using PowerCSharp.Extensions;
string basePath = "/var/www/uploads";
string userFile = "../../etc/passwd"; // malicious attempt
// Throws SecurityException — resolved path escapes basePath (CWE-73)
string safePath = PathExtensions.CombineAndValidate(basePath, userFile);
// Valid relative path resolves normally
string validPath = PathExtensions.CombineAndValidate(basePath, "images/photo.jpg");
// -> "/var/www/uploads/images/photo.jpg"Configuration binding split out from the web-free core
IConfiguration.GetOptions<T>() binds a section to a class implementing IAppOptions, alongside HttpStatusCode classification and HttpRequestMessage cloning for retry logic. Kept in its own package so non-web consumers of Extensions don't inherit ASP.NET Core dependencies.
using PowerCSharp.Extensions.AspNetCore;
public class EmailOptions : IAppOptions
{
public string ConfigSectionPath => "Email";
public string SmtpHost { get; set; } = string.Empty;
}
var emailOptions = builder.Configuration.GetOptions<EmailOptions>();A deliberate bridge off .NET Framework, not a permanent home
Targets net462, net472, and net48 for teams still on legacy ASP.NET/IIS. AsyncHelper.RunSync<T>() runs async code from a sync context without deadlocking, using a dedicated TaskFactory — documented as a migration path toward the modern packages, not a long-term target.
using PowerCSharp.Compatibility;
// Runs async code from a sync context (legacy ASP.NET, console apps)
// without the classic sync-over-async deadlock.
var result = AsyncHelper.RunSync(() => FetchDataAsync());Also in the bundle
Smaller, focused packages that round out the foundation.
PowerCSharp.Core
v2.0.2Foundation only: centralized interfaces and models (IAppOptions, IDynamicFilterProvider<T>, IDynamicOrderProvider<T>). No implementation logic, no third-party dependencies.
PowerCSharp.Utilities
v2.0.2Zero-dependency static helpers: ValidationHelper (email/URL/numeric), FileHelper (SafeReadAllText, SafeWriteAllText), MathHelper (Clamp, Percentage with zero-division protection).
PowerCSharp.Helpers
v2.0.2Security and format-focused: CryptoHelper (SHA256, secure random strings), JsonHelper (never-throws SafeSerialize/SafeDeserialize), EnvironmentHelper (env vars with defaults).
Pair it with the Features engine
Core and Extensions are dependency-free and stand on their own — or layer runtime-toggleable capabilities on top with PowerCSharp.Features.
Explore the Features engine