Orleans integration
Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
This article is the reference for the Aspire Orleans Hosting integration. It enumerates the AppHost APIs — with examples for both AppHost.cs and apphost.ts — that you use to model an Orleans cluster in your AppHost project.
Orleans is a cross-platform framework for building distributed applications that are elastically scalable and fault-tolerant. Unlike other Aspire integrations, the Orleans integration doesn’t create a container. Instead, the Orleans service is modeled as a resource in the AppHost and its configuration is propagated to any project that references it.
Hosting integration
Section titled “Hosting integration”To start building an Aspire app with Orleans, install the 📦 Aspire.Hosting.Orleans NuGet package in your AppHost project:
aspire add Aspire.Hosting.OrleansLearn more about aspire add in the command reference.
Or, choose a manual installation approach:
#:package Aspire.Hosting.Orleans@*<PackageReference Include="Aspire.Hosting.Orleans" Version="*" />aspire add Aspire.Hosting.OrleansLearn more about aspire add in the command reference.
This updates your aspire.config.json with the Orleans hosting integration package:
{ "packages": { "Aspire.Hosting.Orleans": "13.3.0" }}Add an Orleans resource
Section titled “Add an Orleans resource”Call addOrleans (or AddOrleans) to add and return an Orleans service resource builder. The name provided to the Orleans resource is for diagnostic purposes. For most applications, a value of "default" suffices:
var builder = DistributedApplication.CreateBuilder(args);
var orleans = builder.AddOrleans("default");
// After adding all resources, run the app...builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const orleans = await builder.addOrleans("default");
await builder.build().run();Use Azure Storage for clustering and grain storage
Section titled “Use Azure Storage for clustering and grain storage”In an Orleans app, the fundamental building block is a grain. Grains can have durable states that must be persisted somewhere. Azure Blob Storage is one supported location.
Orleans hosts also register themselves in a membership table so silos can find each other and form a cluster. Azure Table Storage is a popular choice for this membership table.
To configure Orleans with Azure Storage clustering and grain storage, first install the 📦 Aspire.Hosting.Azure.Storage NuGet package in the AppHost project:
aspire add azure-storageDie Aspire CLI ist interaktiv; das passende Suchergebnis wählen, wenn gefragt:
Select an integration to add:
> azure-storage (Aspire.Hosting.Azure.Storage)> Other results listed as selectable options...#:package Aspire.Hosting.Azure.Storage@*<PackageReference Include="Aspire.Hosting.Azure.Storage" Version="*" />Then configure the Orleans resource with clustering and grain storage using withClustering (or WithClustering) and withGrainStorage (or WithGrainStorage):
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("storage");var clusteringTable = storage.AddTables("clustering");var grainStorage = storage.AddBlobs("grainstate");
var orleans = builder.AddOrleans("default") .WithClustering(clusteringTable) .WithGrainStorage("Default", grainStorage);
// After adding all resources, run the app...builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const storage = await builder.addAzureStorage("storage");const clusteringTable = await storage.addTables("clustering");const grainStorage = await storage.addBlobs("grainstate");
const orleans = await builder.addOrleans("default") .withClustering(clusteringTable) .withGrainStorage("Default", grainStorage);
await builder.build().run();Any project that references the Orleans resource also inherits a reference to the clusteringTable resource automatically.
Add an Orleans server project
Section titled “Add an Orleans server project”Add a project to your solution as an Orleans server (a silo). Reference the Orleans resource from the server project so that it receives the clustering and storage configuration:
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("storage");var clusteringTable = storage.AddTables("clustering");var grainStorage = storage.AddBlobs("grainstate");
var orleans = builder.AddOrleans("default") .WithClustering(clusteringTable) .WithGrainStorage("Default", grainStorage);
var server = builder.AddProject<Projects.OrleansServer>("orleans-server") .WithReference(orleans);
// After adding all resources, run the app...builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const storage = await builder.addAzureStorage("storage");const clusteringTable = await storage.addTables("clustering");const grainStorage = await storage.addBlobs("grainstate");
const orleans = await builder.addOrleans("default") .withClustering(clusteringTable) .withGrainStorage("Default", grainStorage);
const server = await builder.addProject("orleans-server", "../OrleansServer/OrleansServer.csproj") .withReference(orleans);
await builder.build().run();When you reference the Orleans resource from a project, the dependent storage resources are also referenced transitively.
Add an Orleans client project
Section titled “Add an Orleans client project”Orleans clients communicate with grains hosted in an Orleans cluster. For example, a frontend web app calls grains running on Orleans servers. Reference the Orleans resource using asClient() (or AsClient()) so the project is configured as a client rather than a silo:
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("storage");var clusteringTable = storage.AddTables("clustering");var grainStorage = storage.AddBlobs("grainstate");
var orleans = builder.AddOrleans("default") .WithClustering(clusteringTable) .WithGrainStorage("Default", grainStorage);
var client = builder.AddProject<Projects.OrleansClient>("orleans-client") .WithReference(orleans.AsClient());
// After adding all resources, run the app...builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const storage = await builder.addAzureStorage("storage");const clusteringTable = await storage.addTables("clustering");const grainStorage = await storage.addBlobs("grainstate");
const orleans = await builder.addOrleans("default") .withClustering(clusteringTable) .withGrainStorage("Default", grainStorage);
const client = await builder.addProject("orleans-client", "../OrleansClient/OrleansClient.csproj") .withReference(await orleans.asClient());
await builder.build().run();Create the Orleans server project
Section titled “Create the Orleans server project”Now that the AppHost project is configured, implement the Orleans server project. Add the required NuGet packages:
dotnet add package Aspire.Azure.Data.Tablesdotnet add package Aspire.Azure.Storage.Blobsdotnet add package Microsoft.Orleans.Serverdotnet add package Microsoft.Orleans.Persistence.AzureStoragedotnet add package Microsoft.Orleans.Clustering.AzureStorageIn the Program.cs file of the Orleans server project, add the Azure Storage blob and table clients, then call UseOrleans:
var builder = WebApplication.CreateBuilder(args);
builder.AddKeyedAzureTableServiceClient("clustering");builder.AddKeyedAzureBlobServiceClient("grainstate");builder.UseOrleans();
var app = builder.Build();
app.Run();Example: CounterGrain implementation
Section titled “Example: CounterGrain implementation”The following is a complete example of an Orleans server project, including a grain named CounterGrain:
using Orleans;
var builder = WebApplication.CreateBuilder(args);
builder.AddKeyedAzureTableServiceClient("clustering");builder.AddKeyedAzureBlobServiceClient("grainstate");builder.UseOrleans();
var app = builder.Build();
app.Run();
public interface ICounterGrain : IGrainWithStringKey{ Task<int> GetCountAsync(); Task<int> IncrementAsync();}
[GenerateSerializer]public class CounterState{ [Id(0)] public int Count { get; set; }}
public class CounterGrain : Grain, ICounterGrain{ private readonly IPersistentState<CounterState> _state;
public CounterGrain( [PersistentState("count", "Default")] IPersistentState<CounterState> state) { _state = state; }
public Task<int> GetCountAsync() => Task.FromResult(_state.State.Count);
public async Task<int> IncrementAsync() { _state.State.Count++; await _state.WriteStateAsync(); return _state.State.Count; }}Create an Orleans client project
Section titled “Create an Orleans client project”In the Orleans client project, add the required NuGet packages:
dotnet add package Aspire.Azure.Data.Tablesdotnet add package Aspire.Azure.Storage.Blobsdotnet add package Microsoft.Orleans.Clientdotnet add package Microsoft.Orleans.Persistence.AzureStoragedotnet add package Microsoft.Orleans.Clustering.AzureStorageIn the Program.cs file of the Orleans client project, add the Azure Table Storage client, then call UseOrleansClient:
var builder = WebApplication.CreateBuilder(args);
builder.AddKeyedAzureTableServiceClient("clustering");builder.UseOrleansClient();
var app = builder.Build();
app.MapGet("/", async (IGrainFactory grains) =>{ var grain = grains.GetGrain<ICounterGrain>("counter"); var count = await grain.IncrementAsync(); return Results.Ok(new { count });});
app.Run();The preceding code calls the CounterGrain grain defined in the Orleans server example above.
Enable OpenTelemetry
Section titled “Enable OpenTelemetry”By convention, Aspire solutions include a service defaults project that defines shared configuration and behavior. To configure Orleans for OpenTelemetry, modify the ConfigureOpenTelemetry method in your service defaults project to add the Orleans meters and tracing sources:
public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder){ builder.Logging.AddOpenTelemetry(logging => { logging.IncludeFormattedMessage = true; logging.IncludeScopes = true; });
builder.Services.AddOpenTelemetry() .WithMetrics(metrics => { metrics.AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddRuntimeInstrumentation() .AddMeter("Microsoft.Orleans"); }) .WithTracing(tracing => { tracing.AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddSource("Microsoft.Orleans.Runtime") .AddSource("Microsoft.Orleans.Application"); });
builder.AddOpenTelemetryExporters();
return builder;}Supported providers
Section titled “Supported providers”The Orleans Aspire integration supports a limited subset of Orleans providers:
Clustering:
- Redis
- Azure Storage Tables
Persistence:
- Redis
- Azure Storage Tables
- Azure Storage Blobs
Reminders:
- Redis
- Azure Storage Tables
Grain directory:
- Redis
- Azure Storage Tables
Streaming providers aren’t supported as of Orleans version 8.1.0.