Jakar.Extensions
10.10.0
dotnet add package Jakar.Extensions --version 10.10.0
NuGet\Install-Package Jakar.Extensions -Version 10.10.0
<PackageReference Include="Jakar.Extensions" Version="10.10.0" />
<PackageVersion Include="Jakar.Extensions" Version="10.10.0" />
<PackageReference Include="Jakar.Extensions" />
paket add Jakar.Extensions --version 10.10.0
#r "nuget: Jakar.Extensions, 10.10.0"
#:package Jakar.Extensions@10.10.0
#addin nuget:?package=Jakar.Extensions&version=10.10.0
#tool nuget:?package=Jakar.Extensions&version=10.10.0
Jakar.Extensions
Extensions and helpers for .NET 10: observable and concurrent collections, HTTP, files, security, async LINQ, span and hashing helpers, users and logins, and view models. It is trim and Native AOT compatible. Contributions and ideas are welcome.
Installation
dotnet add package Jakar.Extensions
It brings in Jakar.Json (JSON, including the [JsonModel] source generator) and Jakar.Spans (ValueStringBuilder and other span primitives).
JSON
Since 10.10 the library serializes with System.Text.Json source-generated metadata, and Jakar.Json where it supports the type: no Newtonsoft.Json and no reflection-based serialization.
Models are
IJsonModel<TSelf>types. Put[JsonModel(typeof(YourContext))]on apartialclass, record or struct, and register it in yourJsonSerializerContext. The generator implements the model's members with Jakar.Json when it supports the type (faster, fewer allocations), otherwise with System.Text.Json.[JsonSerializable(typeof(Invoice))] public sealed partial class AppJsonContext : JsonSerializerContext; [JsonModel(typeof(AppJsonContext))] public sealed partial class Invoice : BaseClass<Invoice> { public decimal Total { get; init; } } Invoice invoice = Invoice.FromJson(json); string text = invoice.ToJson();Other types: register their context once at startup with
Json.AddResolver(AppJsonContext.Default), then useJson.Serialize(value)/json.FromJson<T>(), or pass aJsonTypeInfo<T>explicitly.Root-level arrays never need a collection type registered:
JsonModel.FromJsonList(json, Invoice.JsonTypeInfo),invoices.ToJson(),WebHandler.AsJsonList(Invoice.JsonTypeInfo, token).JsonNode/JsonElementhelpers:Get<T>,TryGet<T>,GetOrDefault<T>,TryAdd,TryUpdate,Set,Remove.Older JSON still reads. JSON written by 10.9 and earlier (Newtonsoft.Json) is accepted: case-insensitive property names, numbers in strings, comments and trailing commas.
Migrating from 10.9 and earlier
JToken/JObject/JValueare gone:AdditionalDataisDictionary<string, JsonElement>?.ErrorResponse,WebHandler.AsJson()andFeedBackTrackerExceptionuseJsonNode.ExceptionDetails.Datais aJsonObject, andLoginRequestValue.Datais aJsonElement.
value.ToJson()works forIJsonModel<TSelf>types and arrays, lists and spans of them. For anything else, useJson.Serialize(value).- Your own
IJsonModel<TSelf>types must providestatic JsonTypeInfo<TSelf> JsonTypeInfo: add[JsonModel]. Diagnostic JAKAR_JSON006 has a code fix. PreferenceFile<TSelf>stores{TSelf}.jsonwith typed properties. An existing{TSelf}.iniis imported on first load.- Observable collections serialize their unfiltered contents. For System.Text.Json to do the same when such a collection is a model property, register the closed converter in your context:
Converters = [typeof(ObservableCollectionJsonConverter<Address>)]. Json.Settings/Json.LoadSettingsare replaced byJson.OptionsandJson.AddResolver.ValueStringBuilderandSizesmoved to Jakar.Spans. They keep the same namespace and are type-forwarded, so no code changes.
Base classes
BaseClass/BaseClass<TSelf>: a model base with property change notifications (INotifyPropertyChanging,INotifyPropertyChanged), JSON extension data (AdditionalData), and equality and comparison forTSelf.BaseRecord: the record counterpart, with JSON extension data.
Collections
- Observable:
ObservableCollection<T>,ConcurrentObservableCollection<T>,ObservableDictionary<TKey, TValue>,ObservableConcurrentDictionary<TKey, TValue>,ObservableHashSet<T>. They raise change notifications and can show a filtered view (OverrideFilter); the list types also keep a sort order (Comparer<T>). - Queues and stacks:
ConcurrentDeque<T>,FixedSizedDeque<T>,FixedSizedQueue<T>,LockFreeDeque<T>,LockFreeStack<T>. - Other:
ArrayBuffer<T>(a growable buffer struct),AsyncChannel<T>,ValueLinkedList<T>,MultiDict<TKey>.
HTTP
WebRequester: a wrapper aroundHttpClientthat builds requests against a base URI (IHostInfo), with retries (RetryPolicy).WebHandler: one request. EveryAs*call sends it, retries per the requester's policy, and returns aWebResponse<T>.WebResponse<T>: the result: status, value or error details.Status,MimeType,MimeTypeNames: HTTP status codes, MIME types and their names.
Files
LocalFile,LocalDirectory: read, write, create, delete and enumerate local files and directories.LocalFileWatcher: an observable collection of a directory's files.TempFile,EmbeddedResources,FilePaths.PreferenceFile<TSelf>: typed preferences persisted as JSON.IniConfig: parses and formats INI files.
Security
SecuredString: sensitive text kept in aSecureString.PasswordValidatorandPasswordRequirements: password rules and validation.OneTimePassword: TOTP codes.IDataProtector/IDataProtectorProvider/DataProtector: encrypt and decrypt data.
Errors
ErrorOrResult<T>andError: a value or errors (inspired by ErrorOr).ExceptionDetails: exceptions as serializable data.
Miscellaneous
Validate: string and state validation.Tasks: task helpers such asSafeFireAndForget.Types: type inspection (IsBuiltInType,IsNullableType,IsCollection,IsDictionary,IsList,IsSet,HasInterface,TryGetUnderlyingEnumType,MethodName,MethodSignature, ...).LoginRequest,UserModel,JwtParser: users, logins and tokens.AppVersion: application versions with formatting and parsing.BaseViewModeland theCommand/IAsyncCommandtypes: view models.TelemetrySource,StopWatch: diagnostics.
Method lists
Many of these have several overloads.
- AsyncLinq:
Add,AddDefault,AddOrUpdate,AsAsyncEnumerable,Average,CastSafe,Consolidate,ConsolidateUnique,Enumerate,EnumeratePairs,First,FirstOrDefault,ForEach,ForEachAsync,ForEachParallel,ForEachParallelAsync,GetArray,IsEmpty,Last,LastOrDefault,Max,Min,Random,RandomKeys,RandomValues,Range,Remove,Single,SingleOrDefault,Sorted,ToArray,ToArrayBuffer,ToConcurrentObservableCollection,ToHashSet,ToImmutableArray,ToList,ToObservableCollection,TryAdd,WhenAllParallelAsync,WhereNotNull,WhereNotNullAsync. - Hashes:
Concatenate,GetHash,Hash,Hash128,HashAsync,Hash_MD5,Hash_SHA1,Hash_SHA256,Hash_SHA384,Hash_SHA512,HashAsync_MD5,HashAsync_SHA1,HashAsync_SHA256,HashAsync_SHA384,HashAsync_SHA512,ToBytes,TryGetData. AlsoHashCodeU64/HashCodeU128. - Types:
Construct,GetNullabilityInfo,GetParameterInfo,HasInterface,IsAnyBuiltInType,IsBuiltInNullableType,IsBuiltInType,IsCollection,IsDictionary,IsDictionaryEntry,IsEqualType,IsGenericType,IsInitOnly,IsJsonNode,IsKeyValuePair,IsList,IsNullable,IsNullableType,IsOneOf,IsSet,MethodClass,MethodInfo,MethodName,MethodSignature,TryGetUnderlyingEnumType,TryGetUnderlyingType. - Spans:
All,Any,As,AsArraySegment,AsBytes,AsImmutableArray,AsMemory,AsReadOnlyMemory,AsReadOnlySpan,AsSpan,Average,ClampEnd,ClampStart,Contains,ContainsAll,ContainsAny,ContainsExact,ContainsNone,ConvertToString,CopyTo,Count,Create,CreateSpan,EndsWith,Enumerate,First,FirstOrDefault,GetVectors,IsNullOrWhiteSpace,Join,Last,LastIndexOf,LastOrDefault,Max,Min,QuickSort,RefSelect,Remove,RemoveAll,Replace,Select,SequenceEqual,SequenceEqualAny,Single,SingleOrDefault,Slice,StartsWith,Sum,ToMemory,ToMemoryStream,ToReadOnlyMemory,Trim,TrimEnd,TrimStart,TryAsSegment,TryCopyTo,TryGetCount.
Versioning
Versions follow <.NET major>.<library major>.<library minor>: 10.10.0 targets .NET 10, library major 10, minor 0. See the repository README.
License
MIT. See LICENSE.txt. Contributions are welcome: open an issue or a pull request on GitHub.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- CommunityToolkit.Diagnostics (>= 8.4.2)
- Jakar.Json (>= 10.2.0)
- Jakar.Spans (>= 10.1.0)
- JetBrains.Annotations (>= 2026.2.0)
- Microsoft.CodeAnalysis.CSharp (>= 5.9.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.13)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.13)
- Microsoft.Extensions.Http (>= 10.0.13)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.13)
- Microsoft.Extensions.Options (>= 10.0.13)
- Microsoft.IdentityModel.JsonWebTokens (>= 8.23.0)
- Microsoft.IdentityModel.Tokens (>= 8.23.0)
- Nito.Collections.Deque (>= 1.2.1)
- OneOf (>= 3.0.271)
- OneOf.Extended (>= 3.0.271)
- OneOf.SourceGenerator (>= 3.0.271)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.20.0)
- OpenTelemetry.Instrumentation.Http (>= 1.20.0)
- OpenTelemetry.Instrumentation.Runtime (>= 1.20.0)
- Otp.NET (>= 1.4.1)
- Serilog (>= 4.4.0)
- Serilog.Formatting.Compact (>= 3.0.0)
- Serilog.Sinks.Async (>= 2.1.0)
- Serilog.Sinks.Console (>= 6.1.1)
- Serilog.Sinks.Debug (>= 3.0.0)
- Serilog.Sinks.File (>= 7.0.0)
- System.ComponentModel.Annotations (>= 5.0.0)
- System.IO.Hashing (>= 10.0.13)
- ZLinq (>= 1.5.6)
- ZLinq.FileSystem (>= 1.5.6)
- ZXing.Net (>= 0.16.11)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Jakar.Extensions:
| Package | Downloads |
|---|---|
|
Jakar.Database
Package Description |
|
|
Jakar.Extensions.Blazor
Extensions to aid in development. |
|
|
Jakar.Shapes
Extensions to aid in development. |
|
|
Jakar.Extensions.Serilog
Extensions to aid in development. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 10.10.0 | 52 | 10/17/2026 | |
| 10.9.3 | 203 | 8/26/2026 | |
| 10.9.1 | 154 | 7/2/2026 | |
| 10.9.0 | 150 | 6/19/2026 | |
| 10.8.3 | 198 | 3/11/2026 | |
| 10.8.2 | 159 | 3/11/2026 | |
| 10.8.1 | 164 | 3/11/2026 | |
| 10.8.0 | 169 | 3/2/2026 | |
| 10.7.0 | 163 | 2/17/2026 | |
| 10.6.0 | 177 | 2/16/2026 | |
| 10.5.0 | 190 | 2/4/2026 | |
| 10.4.1 | 189 | 2/2/2026 | |
| 10.4.0 | 179 | 2/2/2026 | |
| 10.3.4 | 189 | 1/28/2026 | |
| 10.3.3 | 200 | 1/22/2026 | |
| 10.3.2 | 188 | 1/22/2026 | |
| 10.3.1 | 194 | 1/21/2026 | |
| 10.3.0 | 172 | 1/21/2026 | |
| 10.2.0 | 201 | 1/8/2026 | |
| 10.1.1 | 210 | 12/30/2025 |
10.10.0: ValueStringBuilder and Sizes moved to the new dependency Jakar.Spans (same namespace, type-forwarded, so no source or binary change); Jakar.Spans adds ValueUtf8Builder and ValueSpanReader<T>. BREAKING: System.Text.Json replaces Newtonsoft.Json; the library is trim and Native AOT compatible (source-generated metadata only). New dependency Jakar.Json (IJsonModel<TSelf>, the [JsonModel] source generator and analyzers, pooled element-wise JSON arrays, SerializeAsStringJsonConverter<T>, plus the Jakar.Json serializer, which [JsonModel] uses behind IJsonModel when it supports the type: most models' ToJson/FromJson now run on it, laid out as Jakar.Json writes ("name" : value) with the context's options mirrored; JsonTypeInfo stays System.Text.Json's); types stay in the Jakar.Extensions namespace. IJsonModel<TSelf> requires static JsonTypeInfo (add [JsonModel]). JToken/JObject/JValue removed: AdditionalData is Dictionary<string, JsonElement>?, ErrorResponse/WebHandler.AsJson/FeedBackTrackerException use JsonNode, ExceptionDetails.Data is JsonObject, LoginRequestValue uses JsonElement. Json.Settings/LoadSettings replaced by Json.Options/AddResolver/GetTypeInfo; generic ToJson<T>(this T) only for IJsonModel types (else Json.Serialize). Typed JsonNode/JsonElement get/add/update/remove helpers. JSON written by 10.x still reads (case-insensitive names, numbers in strings, comments, trailing commas); output keeps PascalCase. PreferenceFile stores {TSelf}.json and imports an existing .ini. Observable collections serialize their unfiltered contents and read in bulk. LocalFile/LocalDirectory serialize as {"FullPath"}. ExceptionDetails(Exception, bool) became Create / CreateWithMethodInfo. WebRequester: AsJson(JsonTypeInfo), AsJsonArray/AsJsonList, BaseClass bodies serialized as their runtime type. Fixes: Json.ToJson(ReadOnlySpan) serialized the whole pooled rental; LocalFile.WriteAsync(string) wrote empty files; LoginRequest copy constructors passed the login as the password; Email.TryParse returned the inverse; GcInfo did not deserialize MemoryInfo. Removed the unused ValueOf package. 10.11.0: BREAKING: IIObservableCollection<TValue> renamed to IObservableCollection<TValue>. BREAKING: Command<TValue> now follows CommunityToolkit.Mvvm AsyncRelayCommand<T> semantics and implements the new IAsyncCommand<TValue>: ExecutionTask, IsRunning, CanBeCanceled, IsCancellationRequested (with PropertyChanged), ExecuteAsync returning Task, Cancel(), NotifyCanExecuteChanged() (CanExecute no longer raises CanExecuteChanged itself), CommandOptions (AllowConcurrentExecutions, FlowExceptionsToTaskScheduler), CreateCancelCommand(); CanExecute is false while running by default; starting a cancellable handler cancels the previous token; Execute rethrows handler failures on the calling context unless FlowExceptionsToTaskScheduler; object parameters of the wrong type throw ArgumentException. Command<TValue>.Executable accepts CancellationToken-taking handlers, adds Execute(object?, TValue?, CancellationToken), is 16 bytes instead of 72, and no longer drops the Task from Func<TValue?, Task> handlers (it is now awaited). Fixed SelfLogger.WriteLine throwing FormatException for named template holes such as {Error}. Internal folder restructure. Removed the unused Portable.BouncyCastle dependency and System.* package references that are part of the net10.0 shared framework. 10.10.0: TelemetrySource uses W3C activity IDs: the process-wide hierarchical default is gone and the StartActivity idFormat default is now Unknown (default parameter values are compiled into call sites, so recompile callers). StartActivity respects the sampler: it returns null instead of throwing when sampled out, no longer forces IsAllDataRequested, the Recorded trace flag (traceFlags is now ActivityTraceFlags?) or Ok status, and keeps the parent tracestate. Constructing a TelemetrySource no longer clears Activity.Current. AppVersion has a TypeConverter, so it binds from configuration strings. TelemetrySpan can target a specific TelemetrySource via TelemetrySpan.Create(TelemetrySource, string).