Zymergi.Core
11.1.1-alpha
dotnet add package Zymergi.Core --version 11.1.1-alpha
NuGet\Install-Package Zymergi.Core -Version 11.1.1-alpha
<PackageReference Include="Zymergi.Core" Version="11.1.1-alpha" />
<PackageVersion Include="Zymergi.Core" Version="11.1.1-alpha" />
<PackageReference Include="Zymergi.Core" />
paket add Zymergi.Core --version 11.1.1-alpha
#r "nuget: Zymergi.Core, 11.1.1-alpha"
#:package Zymergi.Core@11.1.1-alpha
#addin nuget:?package=Zymergi.Core&version=11.1.1-alpha&prerelease
#tool nuget:?package=Zymergi.Core&version=11.1.1-alpha&prerelease
Zymergi.Core
Foundation library for Zymergi SaaS apps: persistence contracts, domain models, engine-neutral search, the IMarkdownRenderer contract, logging, HTTP helpers, and utilities. Other Zymergi.* packages implement these contracts for a specific database, search engine, or host.
Targets .NET 10. This package has no Zymergi project dependencies.
Install
dotnet add package Zymergi.Core
What you get
- Persistence —
IEntity,IRegistrable,IRepository<T>, registry/handle uniqueness, ADO.NET helpers,DbUnitOfWork - Search —
ISearchProvider<T>,ISearchIndexer<T>,IIndexManager, filter AST, facets,SearchCapabilities - Rendering contract —
IMarkdownRenderer. HTML, Markdown, and XSLT implementations are inZymergi.Rendering - Storage & identity contracts —
IBucket/ISimpleObject,IAuthManagementClient - Logging & utilities —
Loggor(Microsoft.Extensions.Logging.ILogger), string/XML/JSON/HTTP extension methods
JSON serialization uses Newtonsoft.Json. Persistence is raw ADO.NET, not Entity Framework. Prefer RemoveAsync() (soft delete) over DeleteAsync().
Usage
Application code depends on the interfaces in this package. MarkdigRenderer and the XSLT pool are in Zymergi.Rendering. Register a concrete adapter for the engine you use:
using Zymergi.Articles;
// Search — pick one adapter at startup
services.AddElasticSearch(config).AddElasticSearchIndex<ArticleSearchDocument>("articles", d => d.Id);
// or AddMeiliSearch / AddSqliteSearch
// Persistence — generic MariaDB repositories live in Zymergi.Data.MariaDb.
// Users, groups, and favorites are registered from Zymergi.Social.MariaDb.
Config
Configuration binding classes for appsettings.json. These types are deserialized by the .NET IConfiguration system and provide strongly-typed access to connection strings and ADO.NET provider factories.
| Type | Purpose |
|---|---|
ConfigSettings<T> |
Generic read-only collection of configuration settings indexed by name |
ConnectionStringSetting |
POCO for a single database connection string entry |
ConnectionStringSettings |
Deserialized array of ConnectionStringSetting from the ConnectionStringSettings section (SectionName) |
DbProviderFactorySetting |
POCO for a single ADO.NET provider factory entry |
DbProviderFactorySettings |
Deserialized array of DbProviderFactorySetting from the DbProviderFactorySettings section (SectionName) |
Data
ADO.NET database access layer built on extension methods rather than an ORM. Provides parameterized query building, transaction management, and the generic repository contracts. Domain repository interfaces live in their domain packages.
Interfaces
| Type | Purpose |
|---|---|
IDbConnectable |
Contract for classes that own a DbConnection and an optional DbUnitOfWork |
IDbConnectionFactory |
Factory contract for creating IDbConnection instances by provider name |
IDbRegistry |
Database-backed IRegistry exposing table name and primary key metadata |
IDbRegistrableRepository<T> |
Database-backed IRegistrableRepository with IDbRegistry support |
Classes
| Type | Purpose |
|---|---|
AppSettingsDbConnectionFactory |
IDbConnectionFactory implementation reading from appsettings.json |
DbUnitOfWork |
Async all-or-nothing transaction wrapper over DbConnection (create via CreateAsync) |
DbPrimaryKeyAttribute |
Marks a property as the database primary key |
DbGeneratedAttribute |
Marks database-generated properties excluded from INSERT/UPDATE |
DbRequiredAttribute |
Marks properties that cannot be null |
StartTimeAttribute |
Marks property as beginning of a searchable timespan |
EndTimeAttribute |
Marks property as end of a searchable timespan |
DbGenerateMode |
Enum specifying column value generation (None, AutoIncrement) |
Extension methods
| Type | Purpose |
|---|---|
DbCommandExtensionMethods |
Parameterize, AddParameter, and ExecuteReaderAsync on DbCommand |
DbConnectionExtensionMethods |
Async extensions for DbConnection (TryOpenAsync, TryCloseAsync, BuildCommand, QueryAsync, ExecuteAsync, ScalarAsync, OpenScopeAsync) |
IDbCommandExtensionMethods |
GetParametersAsString for command diagnostics |
SelectSqlExtensionMethods |
Builds SELECT statements from KeyValuePair collections |
InsertSqlExtensionMethods |
Builds INSERT statements from KeyValuePair collections |
UpdateSqlExtensionMethods |
Builds UPDATE statements from KeyValuePair collections |
DbExpressionExtensionMethods |
Data record column definitions and element extraction |
DbExceptionExtensionMethods |
Elaborates exceptions with DbCommand diagnostic data |
MappingExtensionMethods |
Maps IDataRecord rows to objects and manipulates properties via reflection |
Http
HTTP client utilities for remote data sources. Provides content helpers for JSON and multipart payloads and a generic HTTP-backed repository contract. CachedServiceBase lives in Zymergi.AspNetCore (namespace Zymergi.Http).
| Type | Purpose |
|---|---|
IHttpRepo<T> |
Generic CRUD repository abstraction over an HTTP-backed data source |
JsonContent |
HttpContent subclass for JSON payloads with UTF-8 encoding |
MultipartFormData |
MultipartFormDataContent initialized from a KeyValuePair collection |
HttpClientExtensionMethods |
Extensions for HttpClient configuration (auth headers, decompression) |
HttpExtensionMethods |
Extensions for HTTP serialization (form encoding, cookie XML, page sizing) |
Identity
Provider-neutral auth management contracts. IAuthManagementClient defines a provider-neutral contract for user and role CRUD that is implemented by Zymergi.Identity.Auth0. ClaimsList and ClaimsExtensionMethods live in Zymergi.AspNetCore.
| Type | Purpose |
|---|---|
IAuthManagementClient |
Contract for managing users and roles in an external auth system |
RoleChangedEventArgs |
EventArgs for role add/remove notifications |
RolesReadEventArgs |
EventArgs for roles-read notifications |
UserEventArgs |
EventArgs for user add/remove notifications |
UserRolesEventArgs |
EventArgs for user-roles-read notifications |
UsersEventArgs |
EventArgs for bulk users-read notifications |
Interfaces
Core domain contracts that define the entity and repository model used throughout the system. Every persistable object implements IEntity; objects that need globally unique handles implement IRegistrable. Repositories follow a consistent contract with CRUD, pagination, soft-delete, and event support.
| Type | Purpose |
|---|---|
IEntity |
Base interface for persistable entities with UID and timestamp properties |
IRegistrable |
Extends IEntity with handle, name, and type for registry storage |
IRepository<T> |
Full repository. Inherits the four role interfaces below. Existing callers keep this type |
IReadRepository<T> |
Get, get-removed, and column names |
IWriteRepository<T> |
Initialize, add, import, update, hard delete, and clear |
ISoftDeleteRepository<T> |
Remove, restore, and empty trash |
IRepositoryEvents<T> |
Add, import, read, update, remove, restore, and delete events |
IRegistrableRepository<T> |
Repository for IRegistrable entities indexed by handle |
IRegistry |
Central tracking registry providing repository-like access to all IRegistrable items |
ICommentable |
Contract for entities supporting hierarchical comments |
IJsonSerializable |
Contract for objects convertible to JObject and JSON string |
IMarkdownRenderer |
Contract for CommonMark markdown-to-HTML rendering |
INamed |
Contract for items with a human-readable name |
IPdfRasterDocument |
Contract for accessing bitmap pages from a PDF document |
IPdfRasterPage |
Contract representing a single rasterized PDF page |
Json
Custom Newtonsoft.Json converters for handling non-standard JSON shapes.
| Type | Purpose |
|---|---|
ArrayJsonConverter<T> |
Converter that transparently handles both single items and arrays in a JSON field, always deserializing to a collection |
Logging
Structured logging with performance tracking. Loggor (namespace Zymergi.Logging) is the central static logger. It writes through Microsoft.Extensions.Logging.ILogger from package Microsoft.Extensions.Logging.Abstractions. The host creates the four loggers and configures their sinks. LogEntry / LogRecord capture the when/where/who/what context. PerfTracker measures function execution time and logs results automatically.
using Microsoft.Extensions.Logging;
using Zymergi.Logging;
void Configure(ILoggerFactory factory)
{
Loggor.Initialize(
factory.CreateLogger("Usage"),
factory.CreateLogger("Error"),
factory.CreateLogger("Perf"),
factory.CreateLogger("Diag"));
}
Loggor.WriteUsage(new LogEntry("viewed a page") { Product = "App", Layer = "Web" });
Initialize assigns UsageLogger, ErrorLogger, PerfLogger, and DiagLogger. Each Write* call logs only when that field is set. WriteDiagnostic also requires EnableDiagnostics. WriteError copies the innermost exception message onto ILogEntry.Message and passes the exception to ILogger.Log. The message template names the entry's fields ({Message}, {Product}, {Layer}, and the rest); caller text is a property value.
| Type | Purpose |
|---|---|
Loggor |
Static logger for performance, usage, error, and diagnostic logging via Microsoft.Extensions.Logging.ILogger |
LogEntry |
Comprehensive log entry with when/where/who/what context |
LogRecord |
Persistable LogEntry implementing ILogRecord for database storage |
LoggedException |
Exception class for deserializing logged exceptions from the database |
PerfTracker |
Tracks function execution duration and logs results via Loggor |
ILogEntry |
Contract for log entries with user, location, timing, and performance data |
ILogRecord |
Contract for log entries persistable as database entities |
ILogRepository |
Repository contract for persisting and querying log records |
LogExceptionExtensionMethods |
Extensions for creating LogEntry from exceptions |
Models
Shared base types implementing the IEntity / IRegistrable hierarchy. EntityBase provides the shared UID and timestamp fields; RegistryItem adds handle, name, and type for entities tracked in the central registry.
Domain entity types live in feature packages: articles in Zymergi.Articles, users/groups/comments/submissions in Zymergi.Social.
| Type | Purpose |
|---|---|
EntityBase |
Abstract base class with UID and timestamp properties |
RegistryItem |
Base class for registrable entities with handle, name, and type |
SerializableBase |
Base class providing ToJson() and ToXml() serialization |
KeySecret |
POCO holding a key-secret pair for API authentication |
GetAllViewModel |
Pagination parameters (page, size, orderBy, order) |
EntityEventArgs<T> |
EventArgs carrying a single IEntity |
EntitiesEventArgs<T> |
EventArgs carrying multiple IEntity instances |
Search
Engine-neutral, faceted document-search abstraction. Defines contracts that decouple application code from any specific search engine. Elasticsearch implements them in Zymergi.Search.Elastic, MeiliSearch in Zymergi.Search.Meili, and embedded SQLite in Zymergi.Search.Sqlite; a future engine implements the same contracts and proves itself against the shared conformance suite in tests/Zymergi.Search.Conformance.Tests.
Scope: structured, faceted search — full-text query + filters + facets + sort over a typed document. It is deliberately not the home for vector/semantic search, autocomplete, or recommendations; those would be separate contracts.
Contracts
| Type | Purpose |
|---|---|
ISearchProvider<TDocument> |
Read side: SearchAsync(SearchRequest) → SearchResult<TDocument>, plus a SearchCapabilities feature-detection surface |
ISearchIndexer<TDocument> |
Write side: index / delete / clear documents; a completed task means the change is durable and searchable |
IIndexManager |
Index lifecycle: exists / create (from an IndexDefinition) / drop |
One provider/indexer instance is bound to one index; the document id is extracted via a key selector supplied at construction, so TDocument stays a plain model.
Request model
| Type | Purpose |
|---|---|
SearchRequest |
Query, filter, facets, sort, paging (Offset/Limit), field projection, highlight, recency |
IFilter + TermFilter / TermsFilter / RangeFilter / ExistsFilter / AndFilter / OrFilter / NotFilter |
Closed filter AST every engine can translate (and an in-memory engine can evaluate directly) |
FilterValue |
Closed value union (Text/Int/Real/Bool/Date) with implicit conversions and Of(...) factories — no object boxing |
FacetRequest + TermsFacetRequest / RangeFacetRequest / DateHistogramFacetRequest / StatsFacetRequest |
Facet kinds; the base carries Disjunctive (multi-select faceting — a facet's counts ignore its own field's filter) |
SortClause / SortDirection, HighlightRequest |
Ordering and highlight configuration |
RecencyBoost |
Best-effort relevance boost toward newer documents: a time-decay on a date field that halves every HalfLife of age |
Recency is best-effort — the one exception to the fail-loud rule. Unlike an unsupported facet (which throws UnsupportedSearchFeatureException), a provider that does not support recency (SearchCapabilities.SupportsRecency == false) ignores SearchRequest.Recency silently. An explicit Sort always takes precedence over it.
Result model
| Type | Purpose |
|---|---|
SearchResult<TDocument> |
Hits, TotalCount + TotalCountAccuracy (Exact / LowerBound / Estimate), computed facets, duration |
SearchHit<TDocument> |
The document, optional score, optional highlight fragments |
FacetResult + TermsFacetResult / RangeFacetResult / DateHistogramFacetResult / StatsFacetResult |
Per-facet-kind results |
SearchCapabilities |
What a provider supports (range/date-histogram/stats facets, highlighting, exact totals, recency, max facet values) |
Schema & errors
| Type | Purpose |
|---|---|
IndexDefinition / FieldDefinition / FieldType |
Declares which fields are searchable / filterable / facetable / sortable — required for faceting on engines that must be told up front (MeiliSearch attributes, Elasticsearch mappings) |
SearchTransportException |
Transport / non-success responses, with HTTP status and body |
SearchHttp |
Shared HttpResponseMessage extensions (EnsureSuccessAsync / ReadBodyOrThrowAsync) mapping a non-success status to SearchTransportException — the Elastic and Meili adapters share one shape |
UnsupportedSearchFeatureException |
Thrown when a request asks for a capability the provider does not support (fail loud, never silently drop a facet) |
Engine differences & conventions
These are engine-neutral guarantees; where engines legitimately differ, SearchCapabilities and SearchResult.TotalAccuracy report it explicitly rather than hiding it:
- Total accuracy — Elasticsearch (
track_total_hits) and SQLite (COUNT) return exact totals; MeiliSearch reports an estimate (SupportsExactTotalCount = false,TotalCountAccuracy.Estimate). - Highlighting — Elasticsearch returns multiple fragments per field; MeiliSearch and SQLite (FTS5
highlight()) return the whole field with match tags as a single fragment (the in-memory reference approximates the latter). All fitSearchHit.Highlights(a list per field), but snippet granularity differs. - Relevance score —
SearchHit.Scorecarries the engine's score (_scorefor Elasticsearch,_rankingScorefor MeiliSearch, negatedbm25()rank for SQLite); the in-memory reference leaves itnull. - Range semantics —
RangeFilteris half-open by default (MinInclusive = true,MaxInclusive = false), i.e.[min, max), consistent withRangeFacetbands. Set the flags explicitly for other bounds. - Paging / limits —
Offset/Limitand facetMaxValuesare passed through as requested; there are no framework-imposed upper bounds, but an engine may cap them (e.g. MeiliSearchmaxValuesPerFacetdefaults to 100, surfaced viaSearchCapabilities.MaxFacetValues).
Article search lives in the Zymergi.Articles package (not here).
Storage
Cloud object storage abstractions. Defines provider-neutral contracts for bucket-based CRUD. The AWS S3 implementation lives in Zymergi.Storage.Aws.
| Type | Purpose |
|---|---|
IBucket |
Contract for a cloud storage bucket with key-addressed CRUD, copy, move, and listing |
IBuckets |
Contract for accessing multiple IBucket instances by name |
ISimpleObject |
Contract for a stored object with key, content bytes, and content type |
ISimpleObjectInfo |
Lightweight object metadata (key, bucket, last modified, size) |
Utilities
General-purpose extension methods used across the solution. These are the primary API surface for common operations on strings, collections, XML, JSON, streams, and dates.
| Type | Purpose |
|---|---|
StringExtensionMethods |
String validation, formatting, truncation, and slug generation |
XmlExtensionMethods |
XML document operations and serialization |
JsonExtensionMethods |
JSON parsing and serialization helpers |
ClassExtensionMethods |
Reflection and metadata operations on classes |
DataRecordExtensionMethods |
IDataRecord column access with null handling |
DateTimeExtensionMethods |
DateTime formatting and manipulation |
DictionaryExtensionMethods |
Dictionary merge and lookup operations |
ExceptionExtensionMethods |
Exception message extraction and aggregation |
NvcExtensionMethods |
NameValueCollection operations |
StreamExtensionMethods |
Stream read, write, and conversion |
RSS/Atom helpers (SyndicationFeedExtensionMethods) live in Zymergi.Rendering.
Related packages
| Package | Role |
|---|---|
Zymergi.Data.MariaDb |
MariaDB repositories |
Zymergi.Search.Elastic / .Meili / .Sqlite |
Search engines |
Zymergi.Storage.Aws |
S3 |
Zymergi.Identity.Auth0 |
Auth0 Management API |
Zymergi.AspNetCore |
ASP.NET controllers and startup helpers |
| 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
- Microsoft.Extensions.Configuration (>= 10.0.12)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.12)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.12)
- Newtonsoft.Json (>= 13.0.4)
NuGet packages (15)
Showing the top 5 NuGet packages that depend on Zymergi.Core:
| Package | Downloads |
|---|---|
|
Zymergi.Data.MariaDb
MariaDB repository implementations for Zymergi entities. |
|
|
Zymergi.AspNetCore
ASP.NET Core controllers, authentication filters, and startup extensions for Zymergi. |
|
|
Zymergi.Search.Elastic
Elasticsearch implementation of the engine-neutral faceted-search contracts for Zymergi. |
|
|
Zymergi.Identity.Auth0
Auth0 identity provider implementation for Zymergi. |
|
|
Zymergi.Storage.Aws
AWS S3 object storage implementation for Zymergi. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 11.1.1-alpha | 132 | 10/4/2026 |
| 11.1.0-alpha | 149 | 10/1/2026 |
| 11.0.6-alpha | 179 | 7/10/2026 |
| 11.0.5-alpha | 188 | 7/9/2026 |
| 11.0.4-alpha | 138 | 7/6/2026 |
| 11.0.3-alpha | 134 | 7/6/2026 |
| 11.0.2-alpha | 157 | 6/30/2026 |
| 11.0.1-alpha | 143 | 6/30/2026 |
| 11.0.0-alpha | 129 | 6/29/2026 |