Table of Contents

Orleans.Lattice.Api.Abstractions

This page documents Orleans.Lattice.Api.Abstractions 9.9.0, in the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at README.md, and llms.txt lists every page.

The shared API contract package for Orleans.Lattice - the transport-agnostic service interfaces of the API facades (state, data, auth, backup, schema, replication, telemetry, tree administration, tenant administration, and installable apps), their request / response models, and the typed exceptions those interfaces document, and nothing else.

What is it?

The Orleans.Lattice API surface is built in layers. Each facade package (Orleans.Lattice.Api.State, .Api.Data, .Api.Auth, .Api.Backup, .Api.Schema, .Api.Replication, .Api.Telemetry, .Api.TreeAdmin, .Api.TenantAdmin, .Api.Apps) exposes a transport-agnostic service interface over plain request / response records; each binding (...Grpc) and the Orleans.Lattice.Api.Mcp server projects that same surface onto a wire protocol or tool set.

Orleans.Lattice.Api.Abstractions is the seam between the facades and their consumers. It carries only the contract:

  • The service interfaces - ILatticeStateQuery, ILatticeStateObserver, and ILatticeStateMetricsObserver (state); ILatticeDataApi (data); ILatticeAuthAdmin (auth); ILatticeBackupControl and ILatticeBackupOperations (backup); ILatticeSchemaControl (schema); ILatticeReplicationControl and ILatticeReplicationStatus (replication); ILatticeTelemetry (telemetry); ILatticeTreeAdmin (tree administration); ILatticeTenantAdmin, ILatticeTenantAccessAdmin, ILatticeTenantGrantAdmin, ILatticeTenantQuotaUsage, ILatticeTenantRegionAdmin, and ILatticeTenantSelfService (tenant administration); ILatticeAppsControl, ILatticeAppRoleBindings, ILatticeAppCatalog, ILatticeAppWorkspace, and ILatticeAppBridge (installable apps: control, role re-binding, catalogue, workspace, and the app UI bridge); and ILatticeRegionCatalog (region discovery).
  • Their request / response models - the results, pages, records, and requests those interfaces exchange, each with its stable Orleans serialization alias.
  • Their typed exceptions - the faults the interfaces document, for example LatticeStateCursorExpiredException (state), TelemetryBackendException, TelemetryQueryBoundsException and TelemetryQueryNotFoundException (telemetry), TenantNotFoundException and its tenant-administration siblings, and TreeNotEmptyException and BulkLoadOrderException (tree administration).

Long-running operations contract

The Orleans.Lattice.Api.Operations namespace carries the shared accept-then-poll contract for facade work that can outlast a caller request. ILatticeOperations exposes GetOperationStatusAsync, ListOperationsAsync, and CancelOperationAsync; LatticeOperationHandle, LatticeOperationStatus, LatticeOperationScope, LatticeOperationListRequest, and LatticeOperationPage are the common DTOs. Backup is the first facade to implement it through ILatticeBackupOperations; see Long-running operations and Backup operations.

Region contract

The Orleans.Lattice.Api.Region namespace carries the transport-agnostic region-discovery contract, so any consumer - the MCP lattice_list_regions tool today, a future Explorer UI or gRPC binding - reads the same region model rather than a surface-specific type:

  • ILatticeRegionCatalog - ListRegionsAsync lists the regions a server can route to, current region first.
  • LatticeRegionDescriptor - one region's id, cluster id, whether it is the current region, its per-group reachability, and - on a tenant-scoped discovery call only - the asserting tenant's standing in that region (TenantScope; null otherwise).
  • LatticeRegionGroupReachability - whether a facade group is reachable in a region and the endpoint it is served at.
  • LatticeRegionTenantScope - one tenant's standing in one region: the tenant id, whether an operator has allowed the region for it, its per-region residency lifecycle status, and whether it is resident there.

The package has no implementation, no registration extension, and no background work. Facade packages reference it and implement the interfaces; binding and MCP packages reference it and consume them.

Why it exists

Before this package the facade service interfaces were internal to each facade package, so every consumer that needed the contract - the gRPC bindings and the co-hosted MCP server - had to be granted InternalsVisibleTo into the facade assembly (and, for the MCP server, into the core assembly as well). That coupled a consumer to a producer's private surface across several assemblies.

Publishing the contract as a real, versioned public package removes those cross-package internal-visibility grants: a binding evolves against a stable public contract rather than another package's internals, and internal inside each facade goes back to meaning "safe to change". The interfaces keep their original Orleans.Lattice.Api.{State,Data,Auth,Backup,Schema} namespaces, so existing consumers compile unchanged; the later contracts follow the same one-namespace-per-facade pattern (Orleans.Lattice.Api.Replication, .Telemetry, .TreeAdmin, .TenantAdmin, .Apps, and the region-discovery .Region).

Core properties

  • Contract-only. Interfaces, DTOs and their typed exceptions, no behaviour. There is nothing to register from this package directly.
  • Stable wire identity. Every serializable model keeps its existing [Alias], so the move between assemblies is wire-compatible: persisted and in-flight payloads are unaffected.
  • Source-compatible. Namespaces are unchanged, so a consumer's using directives and type references keep resolving after the move.
  • Trusted system-origin seam. A co-hosted infrastructure consumer that must run a trusted, gate-bypassing introspection uses the public LatticeSystemOrigin seam in the core library rather than an internal-visibility grant.

Usage

You do not register anything from this package directly. Register a facade (which implements these contracts); the now-public interface then resolves straight from DI for a co-hosted, in-process consumer, with no InternalsVisibleTo grant into the facade package:

var builder = WebApplication.CreateBuilder();

builder.Host.UseOrleans(silo =>
{
    silo
        .AddLattice((s, storageName) => s.AddMemoryGrainStorage(storageName))
        .AddLatticeStateApi();
});

var app = builder.Build();

// ILatticeStateQuery is public, so a co-hosted consumer resolves the contract
// directly from DI - no InternalsVisibleTo into Orleans.Lattice.Api.State.
ILatticeStateQuery stateQuery = app.Services.GetRequiredService<ILatticeStateQuery>();

For a remote surface, add the matching binding (which consumes the same contract). See the facade package docs for the full registration story: