.NET SDK
.NET SDK for building EvidentSource applications and server-side WASM components.
Status: Stable
SDK Components
Section titled “SDK Components”| Component | Description |
|---|---|
| EvidentSource.Core | Core library: events, selectors, constraints, identifiers |
| EvidentSource.Client | Client library: gRPC connectivity to EvidentSource servers |
| EvidentSource.Functions | Server Functions library: WASM components for state changes and state views |
Requirements
Section titled “Requirements”- .NET 10.0 or later
- For WASM components: .NET WASI workload (
dotnet workload install wasi-experimental)
Installation
Section titled “Installation”# Clone the repositorygit clone https://github.com/evidentsystems/evidentsource-sdks.gitcd evidentsource-sdks/dotnet
# Build all packagesdotnet build
# Run testsdotnet testQuick Start
Section titled “Quick Start”Client Usage
Section titled “Client Usage”using EvidentSource.Client;using EvidentSource.Core.Domain.Identifiers;using EvidentSource.Core.Domain.Events;
// Connect to EvidentSourceawait using var client = await EvidentSourceClient.ConnectAsync("http://localhost:50051");
// Connect to a databasevar conn = await client.ConnectAsync(DatabaseName.Create("my-database"));
// Transact eventsvar db = await conn.Transaction() .Event(new ProspectiveEvent { Id = Guid.NewGuid().ToString(), Stream = "accounts/123", EventType = "com.example.account.opened", Subject = "123", Data = EventData.FromString("{\"name\": \"Alice\"}"), DataContentType = "application/json" }) .CommitAsync();
Console.WriteLine($"New revision: {db.Revision}");Server Functions Usage
Section titled “Server Functions Usage”using EvidentSource.Functions.Adapters;using EvidentSource.Functions.Database;
public record OpenAccountCommand(string AccountId, string Name, decimal InitialDeposit);
public sealed class OpenAccountStateChange : JsonStateChangeAdapter<OpenAccountCommand>{ protected override DecideResult Decide(IDatabase db, OpenAccountCommand cmd, StateChangeMetadata metadata) { // Query existing state var existing = db.ViewState<AccountSummary>("account-summary", 1, [("account_id", cmd.AccountId)]);
if (existing?.Data is not null) throw StateChangeException.Conflict("Account already exists");
// Return events to emit return DecideResult.Single(new ProspectiveEvent { Id = Guid.NewGuid().ToString(), Stream = $"accounts/{cmd.AccountId}", EventType = "com.example.account.opened", Subject = cmd.AccountId, Data = EventData.FromString(JsonSerializer.Serialize(new { cmd.AccountId, cmd.Name })), DataContentType = "application/json" }); }}Building WASM Components
Section titled “Building WASM Components”Prerequisites
Section titled “Prerequisites”# Install WASI workloaddotnet workload install wasi-experimentalBuilding
Section titled “Building”# Build a state change as WASM (Windows only)cd examples/SavingsAccount/state-changes/OpenAccountdotnet publish -c Release -p:BuildingForWasm=true
# The WASM component is at:# bin/Release/net10.0/wasi-wasm/publish/OpenAccount.wasmProject Configuration
Section titled “Project Configuration”State change and state view projects use conditional compilation:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net10.0</TargetFramework> <RuntimeIdentifier Condition="'$(BuildingForWasm)' == 'true'">wasi-wasm</RuntimeIdentifier> <OutputType>Exe</OutputType> <PublishTrimmed Condition="'$(BuildingForWasm)' == 'true'">true</PublishTrimmed> </PropertyGroup>
<ItemGroup Condition="'$(BuildingForWasm)' == 'true'"> <PackageReference Include="BytecodeAlliance.Componentize.DotNet.Wasm.SDK" /> <Wit Include="path/to/decider.wit" World="state-change" /> </ItemGroup></Project>Examples
Section titled “Examples”| Example | Description |
|---|---|
| TodoMVC | Classic todo list with CRUD operations |
| Savings Account | Complete banking example with interest calculations |
Project Structure
Section titled “Project Structure”dotnet/├── src/│ ├── EvidentSource.Core/ # Core library│ ├── EvidentSource.Client/ # Client library│ └── EvidentSource.Functions/ # Server Functions library├── examples/│ ├── TodoMvc/ # Todo list example│ └── SavingsAccount/ # Banking example└── tests/ ├── EvidentSource.Core.Tests/ └── EvidentSource.Client.Tests/Features
Section titled “Features”Client Library
Section titled “Client Library”- Connection management with automatic reconnection
- Transaction builder with fluent API
- State change execution
- Event queries with flexible selectors
- Bi-temporal queries
- Speculative queries
Server Functions Library
Section titled “Server Functions Library”StateChangeAdapter<TCommand>- Base class for state changesStateViewAdapter<TState, TEvent>- Base class for state viewsJsonStateChangeAdapter/JsonStateViewAdapter- JSON helpersMockDatabase- Testing supportTestEventBuilder- Test event construction
API Reference
Section titled “API Reference”API documentation will be available on NuGet when packages are published.
Next Steps
Section titled “Next Steps”- Getting Started - Build your first EvidentSource application
- State Changes - Learn about command handling
- State Views - Learn about view materialization