Skip to content

.NET SDK — feature blocks & architecture

The SDK is a minimal mandatory core plus a set of optional, stackable feature blocks. You assemble a client by taking the core and adding only the blocks you need: a connected desktop app takes the online transport and metering blocks; an air-gapped device takes offline activation and a file cache instead.

Blocks are described here by ID, responsibility and dependencies, not by .NET types alone. That makes the model language-neutral: a non-.NET client — the shipped C/C++ interop, say — can implement a deliberate subset (license validation and an offline cache, with no HTTP stack at all) and still be conformant. The .NET packages are one implementation of this model; Client.OfflineStore is one example of an add-on stacking on the core.

Every block has a defined absent behavior — when a block is missing, the SDK degrades to a known state rather than failing. Those rules are in Spec rules.

Each block has a stable ID, a responsibility, the blocks it requires, and the current .NET types and package that implement it.

Block Requires .NET types Package
CORE-VALIDATE (mandatory) SecureLicenseTokenValidation, SecureTokenAccess, LicenseClock, LicenseClaims, RsaPublicKey, ILicensePublicKeyProvider Client.LicenseConsumer
CORE-SESSION CORE-VALIDATE LicenseService, LicenseSession, LicenseClient, LicenseClientBuilder Client.LicenseConsumer
IDENTITY-BINDING INodeIdProvider, IComponentNodeIdProvider, Sha256FingerprintSigner, ILicenseKeyProvider, IApplicationInfoProvider Client.LicenseConsumer
STORE-MEMORY / STORE-FILE CORE-VALIDATE InMemoryLicenseStore, LicenseFileStore, AtomicFile Client.LicenseConsumer
METER-RECORD (+ METER-RECORD-FILE) CORE-SESSION ITransactionStore, InMemoryTransactionStore, FileTransactionStore, UsageReporter, ScheduledUsageReporter Client.LicenseConsumer
METER-UPLOAD METER-RECORD + TRANSPORT-HTTP ITransactionProcessor, TransactionsToMonetizeServerConnector, TransactionUploadScheduler Client.LicenseConsumer.Connected
METER-BALANCE TRANSPORT-HTTP IAssetConsumption, AssetBalanceConsumption, NullAssetConsumption Connected
ENTITLEMENTS CORE-VALIDATE IFeatureValidation, FeatureValidation Client.LicenseConsumer
TRANSPORT-HTTP CORE-SESSION HttpLicenseProvider, LicenseRefreshScheduler (activation path); HttpConnector + Client.Provisioning Connected
OFFLINE-ACTIVATION CORE-VALIDATE, IDENTITY-BINDING, STORE-FILE request / response / receipt exchange Client.OfflineStore
HOSTING-ASPNET / HOSTING-MULTITENANT TRANSPORT-HTTP DI root, hosted services, OIDC, OTel / Finbuckle multi-tenant Client.AspNetCore
ADMIN TRANSPORT-HTTP provider-side management APIs Client.Admin + Client.Provisioning
  • CORE-VALIDATE — verifies the JWS RS256 license token against a pinned public key, with a monotonic clock, the validity window and license claims. This is the trust root.
  • CORE-SESSION — the acquire / cache / refresh lifecycle: provider→store fallback, single-flight acquisition gates, and the client builder.
  • IDENTITY-BINDING — node-id and fingerprint providers, the license-key source and app identity: the inputs that bind a license to a machine and application.
  • STORE-MEMORY / STORE-FILE — the license cache: in-process, or a durable atomic-write file cache.
  • METER-RECORD — local usage buffering; METER-RECORD-FILE adds an HMAC-chained, tamper-evident file log.
  • METER-UPLOAD — drains buffered usage to the server on a schedule.
  • METER-BALANCE — server-side asset consumption: a non-binding check, and the commit that binds.
  • ENTITLEMENTS — feature and entitlement checks over license claims.
  • TRANSPORT-HTTP — online activation and refresh: auth, circuit breaker and retry.
  • OFFLINE-ACTIVATION — air-gapped activation through a request / response / receipt exchange.
  • HOSTING-ASPNET / HOSTING-MULTITENANT — the application host: DI root, hosted services, OIDC, OpenTelemetry and Finbuckle multi-tenant support.
  • ADMIN — provider-side management APIs.
  • CORE-VALIDATE is mandatory and must be Full in every conformant client. It is the license trust root.
  • Every other block is optional. A client declares which blocks it implements, rated Full / Partial / None per block.
  • Each omitted block has a defined absent behavior:
    • No provider present → no refresh scheduler runs; the client operates from the store only.
    • TRANSPORT-HTTP absent → store-only activation (licenses come from the cache, not the network).
    • METER-BALANCE absent → NullAssetConsumption is used (consumption calls are no-ops).
    • METER-UPLOAD absent → OFFLINE-ACTIVATION receipt export/import is the alternative drain for METER-RECORD: buffered usage leaves the machine through the receipt exchange instead of an HTTP upload.

The blocks group into three tiers. Add-ons depend on the core, and the core on the foundation — never the reverse. The core’s only foundation dependency is the wire DTO contracts; the HttpConnector transport enters with the Connected add-on, which is what keeps the core HTTP-free.

opt-in add-on packages Connected HTTP · upload · balance OfflineStore air-gapped activation ASP.NET Host DI · hosting · OpenTelemetry Admin provider management APIs Core package netstandard2.0 · HTTP-free validate · session · identity store · metering · entitlements depends on Foundation HttpConnector · wire DTO contracts
  • Core package — HTTP-free, targets netstandard2.0 for broad reach. Holds CORE-VALIDATE, CORE-SESSION, IDENTITY-BINDING, STORE-MEMORY / STORE-FILE, METER-RECORD and ENTITLEMENTS. A client built from the core alone validates licenses, binds identity, caches to memory or disk, records usage locally and enforces entitlements — with no network stack.
  • Add-on packages — opt-in, each stacks on the core: Connected (TRANSPORT-HTTP + METER-UPLOAD + METER-BALANCE), OfflineStore (OFFLINE-ACTIVATION), ASP.NET Host (HOSTING-ASPNET / HOSTING-MULTITENANT) and Admin (ADMIN).
  • Foundation — shared low-level pieces every online tier builds on: the HttpConnector transport and the wire DTO contracts.

A profile is a named assembly of blocks. The matrix rates each block per profile as Full, Partial or None; where a block ships as an add-on, the cell names the package that provides it.

dotnet-min dotnet-desktop dotnet-full cpp-embedded cpp-connected (shipped) (shipped) CORE-VALIDATE CORE-SESSION IDENTITY-BINDING STORE-MEMORY STORE-FILE METER-RECORD METER-UPLOAD METER-BALANCE ENTITLEMENTS TRANSPORT-HTTP OFFLINE-ACTIVATION HOSTING-ASPNET/MT ADMIN Full Full Full Full Full Full Full Full Partial Full Full Full Full Partial Full Full Full Full Full Full Full Full Full Full Full Full Full Full Connected Connected Full Connected Connected Full Full Full Full Full Full Connected Connected Full OfflineStore OfflineStore OfflineStore import-only import-only Full Admin Full Partial / provided by the named add-on package None (see the absent-behavior rules)
  • dotnet-min — the core package only, no HTTP. Validation, session, identity, both stores, metering and entitlements are Full; offline activation is available by adding OfflineStore. No upload, balance, HTTP transport, hosting or admin.
  • dotnet-desktop — core + Connected. Adds online activation/refresh, usage upload and server-side balance.
  • dotnet-full — core + Connected + ASP.NET Host (and Admin for provider-side management). Every block is Full.
  • cpp-embedded (shipped) — the lean subset, the shipped libmonetizeit configured without a server URL (store-only): CORE-VALIDATE Full; STORE-FILE and ENTITLEMENTS Full; OFFLINE-ACTIVATION import-only (it imports responses and receipts but does not originate the exchange); no HTTP transport, hosting or admin. Being the same binary as cpp-connected, it exceeds the profile’s minimum in places (session, identity and local METER-RECORD work offline too).
  • cpp-connected (shipped) — cpp-embedded plus the online path: session, identity, all metering and HTTP transport are Full; offline activation stays import-only; no hosting or admin. Implemented by compiling the .NET consumer core with Native AOT behind the C ABI in the SDK repository’s dotnet/capi (monetizeit.h), consumed from C++ via the header-only RAII wrapper in cpp/capi.