### Start Troolio Server with Defaults Source: https://github.com/fifty3north/troolio/blob/main/README.md Starts the Troolio server using EventStore defaults. Pass the application name, assemblies to scan, and service configuration delegates. ```csharp await Startup.StartWithDefaults("Shopping", new[] { typeof(IShoppingListActor).Assembly, // Sample.Shared typeof(ShoppingListActor).Assembly // Sample.Host.App }, configureServices); ``` -------------------------------- ### Configure Services with DbContext Source: https://github.com/fifty3north/troolio/blob/main/README.md Example of configuring services using an Action delegate. This specific example adds a DbContext for ShoppingLists. ```csharp Action configureServices = (s) => { s.AddDbContext(); }; ``` -------------------------------- ### Configure Event Store Client Source: https://github.com/fifty3north/troolio/blob/main/README.md Configure the EventStore client for Troolio. This example shows a single-node setup. ```json "Shopping:Storage": { "EventStoreCluster": "false", "EventStorePort": "1113", "EventStoreHosts": "eventstore" } ``` -------------------------------- ### Configure Services with Singleton Source: https://github.com/fifty3north/troolio/blob/main/README.md Example of configuring services to add a singleton implementation. This registers IAllShoppingListsActor with DummyAllShoppingListsActor. ```csharp Action configureServices = (s) => { s.AddSingleton(); }; ``` -------------------------------- ### Configure Local Development Host Source: https://github.com/fifty3north/troolio/blob/main/README.md Configure the host for local development without Docker. This setup uses in-memory infrastructure for events and discovery, suitable for local testing only. ```csharp var host = Host .CreateDefaultBuilder(args) .TroolioServer(appName, new[] { typeof(IShoppingListActor).Assembly, // Sample.Shared typeof(ShoppingListActor).Assembly // Sample.Host.App }, configureServices); await host.RunAsync(); ``` -------------------------------- ### Get Troolio Client from Host Source: https://github.com/fifty3north/troolio/blob/main/README.md Retrieves the ITroolioClient instance from the built host's service provider. This client is used to interact with the Troolio server. ```csharp var client = host.Services.GetRequiredService(); ``` -------------------------------- ### Define a Projection Actor in C# Source: https://github.com/fifty3north/troolio/blob/main/README.md Projections are similar to orchestrations but execute after a transaction completes successfully. They are suitable for side effects like sending emails. This example listens to an actor stream and sends an email notification upon a specific event. ```csharp [RegexImplicitStreamSubscription("AllShoppingListsActor-.* אמ")] public class ShoppingListProjectionActor : ProjectionActor { async Task On(EventEnvelope e) { string email = "dummy@somewhere.com"; ShoppingListQueryResult result = await System.ActorOf(e.Event.ListId.ToString()).Ask(new ShoppingListDetails()); await System.ActorOf(Constants.SingletonActorId).Tell(new SendEmailNotification(e.Event.Headers, email, result.Title)); } } ``` -------------------------------- ### Define an Orchestration Actor in C# Source: https://github.com/fifty3north/troolio/blob/main/README.md Orchestrations listen to actor event streams and can raise commands or events. They are part of the transaction, so failure causes the entire transaction to fail. This example subscribes to a specific actor stream and is marked as Reentrant and StatelessWorker for performance. ```csharp [RegexImplicitStreamSubscription("ShoppingListActor-.* אמ")] [Reentrant] [StatelessWorker] public class AllShoppingListsOrchestrationActor : OrchestrationActor { public async Task On(EventEnvelope e) { await System.ActorOf(Constants.SingletonActorId).Tell(new AddShoppingList(e.Event.Headers, Guid.Parse(e.Id))); } } ``` -------------------------------- ### Create Command Line Client Host Builder Source: https://github.com/fifty3north/troolio/blob/main/README.md Sets up a host builder for a command-line client. It configures services to add the Troolio client, specifying the client name and relevant assemblies. ```csharp var hostBuilder = Host.CreateDefaultBuilder(args); hostBuilder.ConfigureServices(services => services.AddTroolioClient("Shopping", new[] { typeof(IShoppingListActor).Assembly })); var host = hostBuilder.Build(); host.Start(); ``` -------------------------------- ### Local Development appsettings.json (No Docker) Source: https://github.com/fifty3north/troolio/blob/main/README.md Appsettings.json configuration for local development without Docker. This enables in-memory storage and discovery. ```json { "{appName}:Clustering": { "Storage": "Local" }, "snapshotThreshold": "100" } ``` -------------------------------- ### Local Development appsettings.json (Docker) Source: https://github.com/fifty3north/troolio/blob/main/README.md Appsettings.json configuration for local development with Docker. This specifies connection strings for the Azure Storage emulator and cluster details. ```json { "{appName}:Clustering": { "ConnectionString": "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;TableEndpoint=http://azurite:10002/devstoreaccount1", "ClusterId": "shopping-dev", "ServiceId": "shopping-service-dev" } } ``` -------------------------------- ### Flush Tracing Log with Ask Query Source: https://github.com/fifty3north/troolio/blob/main/README.md Retrieves the tracing log by issuing a Flush query to the singleton actor. The result contains all issued commands and events since tracing was enabled. ```csharp var tracingLog = await _client.Ask(Constants.SingletonActorId, new Flush()); ``` -------------------------------- ### Configure Azure Table Storage Clustering Source: https://github.com/fifty3north/troolio/blob/main/README.md Set up clustering using Azure Table Storage for multi-host node requirements. Ensure the connection string is valid for development and testing. ```json "Shopping:Clustering": { "ConnectionString": "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;TableEndpoint=http://azurite:10002/devstoreaccount1", "ClusterId": "shopping-dev", "ServiceId": "shopping-service-dev" } ``` -------------------------------- ### Handle Command: AddItemToList in ShoppingListActor Source: https://github.com/fifty3north/troolio/blob/main/README.md Handles the `AddItemToList` command within the `ShoppingListActor`. It performs authorization checks and validates for item existence before yielding an `ItemAddedToList` event. Throws `UnauthorizedAccessException` or `ItemAlreadyExistsException` if validation fails. ```csharp public IEnumerable Handle(AddItemToList command) { if (!(this.State.Author == command.Headers.UserId || this.State.Collaborators.Contains(command.Headers.UserId))) { throw new UnauthorizedAccessException(); } if (this.State.Items.Any(i => i.Name == command.payload.Description)) { throw new ItemAlreadyExistsException(); } yield return new ItemAddedToList(Guid.NewGuid(), command.payload.Description, command.payload.Quantity, command.Headers); } ``` -------------------------------- ### Enable Tracing with Tell Command Source: https://github.com/fifty3north/troolio/blob/main/README.md Enables tracing on the Trool.io client by sending an EnableTracing command to the singleton actor. This allows monitoring of commands and events. ```csharp await client.Tell(Constants.SingletonActorId, new EnableTracing()); ``` -------------------------------- ### Add API Client Singleton Source: https://github.com/fifty3north/troolio/blob/main/README.md Adds the Troolio client as a singleton to the API's service collection. Requires specifying assemblies, client name, and a configuration builder. ```csharp builder.Services.AddSingleton( new TroolioClient(new[] { typeof(IAllShoppingListsActor).Assembly }, "Shopping", configurationBuilder)); ``` -------------------------------- ### Define Command: AddItemToList Source: https://github.com/fifty3north/troolio/blob/main/README.md Defines a command to add an item to a shopping list. It includes metadata, item name, and quantity. This record inherits from `Command`. ```csharp public record AddItemToList(Metadata Headers, string Name, int Quantity) : Command(Headers); ``` -------------------------------- ### Configure Message Queue Provider Source: https://github.com/fifty3north/troolio/blob/main/README.md Dependency inject an IMessageQueueProvider for batch commands. The InMemoryMessageQueueProvider is suitable for development but not production. ```csharp Action configureServices = (s) => { s.AddSingleton(new F3N.Providers.MessageQueue.InMemoryMessageQueueProvider()); }; ``` -------------------------------- ### Add Batch Job to Actor Source: https://github.com/fifty3north/troolio/blob/main/README.md Add a batch job to the system by creating a command, retrieving the actor path, and sending an AddBatchJob message. ```csharp var command = new SendEmailNotification(e.Event.Headers, "someone@somewhere.com", "test email"); ``` ```csharp var actorPath = System.ActorOf(Constants.SingletonActorId).Path; ``` ```csharp await System.ActorOf(Constants.SingletonActorId) .Tell(new AddBatchJob(actorPath, command)); ``` -------------------------------- ### Configure Local Clustering Source: https://github.com/fifty3north/troolio/blob/main/README.md Enable local clustering for improved robustness in Troolio. This setting is configured in appsettings.json. ```json "Shopping:Clustering": { "Storage": "Local" } ``` -------------------------------- ### Define a Read Model Orchestrator in C# Source: https://github.com/fifty3north/troolio/blob/main/README.md This C# class acts as an orchestrator for updating a 'ShoppingList' read model. It subscribes to multiple actor streams and defines 'Handle' methods to map source event properties to the read model's primary key, ensuring the read model is updated correctly. ```csharp [RegexImplicitStreamSubscription("ShoppingListActor-.* אמ")] [RegexImplicitStreamSubscription("AllShoppingListsActor-.* אמ")] public class ShoppingReadModelOrchestrator : ReadModelOrchestrator, IShoppingReadModelOrchestrator, IGrainWithGuidCompoundKey { public ShoppingReadModelOrchestrator(IStore store) : base(store) { } public string Handle(EventEnvelope ev) => ev.Id.ToString(); public string Handle(EventEnvelope ev) => ev.Id.ToString(); public string Handle(EventEnvelope ev) => ev.Id.ToString(); public string Handle(EventEnvelope ev) => ev.Event.ListId.ToString(); } ``` -------------------------------- ### Configure Snapshot Threshold Source: https://github.com/fifty3north/troolio/blob/main/README.md Adjust the snapshot threshold to control how often actor states are snapshotted. The default is 100 events. ```json { "snapshotThreshold": 5 } ``` -------------------------------- ### Define Event: ItemAddedToList Source: https://github.com/fifty3north/troolio/blob/main/README.md Represents an event that signifies an item has been added to a list. It includes metadata, a unique item ID, the item's description, and quantity. This record inherits from `Event`. ```csharp public record ItemAddedToList(Metadata Headers, string Name, int Quantity) : Event(Headers); ``` -------------------------------- ### Define a Read Model in C# Source: https://github.com/fifty3north/troolio/blob/main/README.md Read models are special orchestrations that update a queryable data model based on events. This C# record defines the structure of a 'ShoppingList' read model, including methods to update its state based on various events like 'NewListCreated' and 'ItemAddedToList'. ```csharp public record ShoppingList : TroolioReadModel { public ShoppingList(Guid id) => Id = id; public Guid Id { get; } public string Title { get; private set; } public Guid OwnerId { get; private set; } public ImmutableArray Items { get; private set; } = ImmutableArray.Empty; public string JoinCode { get; private set; } public ShoppingList On(EventEnvelope ev) => this with { Title = ev.Event.Title, OwnerId = ev.Event.Headers.UserId }; public ShoppingList On(EventEnvelope ev) => this with { Items = Items.Add(new ShoppingListItem(ev.Event.ItemId).On(ev)) }; public ShoppingList On(EventEnvelope ev) => this with { Items = Items.RemoveAt( Items.FindIndex((i) => i.Id == ev.Event.ItemId)) }; public ShoppingList On(EventEnvelope ev) => this with { JoinCode = ev.Event.joinCode }; } ``` -------------------------------- ### Define State: ShoppingListState Source: https://github.com/fifty3north/troolio/blob/main/README.md Represents the state of a shopping list, containing an immutable list of `ShoppingListItemState` objects. This is a record type. ```csharp public record ShoppingListState(ImmutableList Items) ``` -------------------------------- ### Disable Tracing with Tell Command Source: https://github.com/fifty3north/troolio/blob/main/README.md Disables tracing by sending a DisableTracing command to the singleton actor. This stops the logging of commands and events. ```csharp await client.Tell(Constants.SingletonActorId, new DisableTracing()); ``` -------------------------------- ### Handle Event: ItemAddedToList in ShoppingListActor Source: https://github.com/fifty3north/troolio/blob/main/README.md Handles the `ItemAddedToList` event by updating the actor's state. It adds a new `ShoppingListItemState` to the `Items` list within the `ShoppingListState`. ```csharp public void On(ItemAddedToList ev) { State = State with { Items = State.Items.Add(new ShoppingListItemState(ev.ItemId, ev.Description, ItemState.Pending, ev.Quantity)) }; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.