# Generated Actor Client Example An example of generating a strongly-typed actor client. ## Prerequisites - [.NET 6+](https://dotnet.microsoft.com/download) installed - [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/) - [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/) - [Dapr .NET SDK](https://docs.dapr.io/developing-applications/sdks/dotnet/) ## Overview Two options for invoking actor methods exist in the Dapr .NET SDK, a strongly-type (remoting) option and a loosely-typed (non-remoting) option. Each has its own advantages and disadvantages. A "middle" option also exists that combines the two and gains benefits of both without some of the disadvantages of either. Using .NET Source Generators, the Dapr .NET SDK can generate a strongly-typed client implementation that uses loosely-typed method invocation under the covers. Strongly-typed clients are generated by: 1. Referencing the `Dapr.Actors.Generators` NuGet package. ```xml ``` 1. Add the `Dapr.Actors.Generators.GenerateActorClientAttribute` to the actor interface. ```csharp using Dapr.Actors.Generators; namespace Sample; internal sealed record SampleState(string Value); [GenerateActorClient] internal interface ISampleActor { [ActorMethod(Name = "GetState")] Task GetStateAsync(CancellationToken cancellationToken = default); [ActorMethod(Name = "SetState")] Task SetStateAsync(SampleState state, CancellationToken cancellationToken = default); } ``` > The `Dapr.Actors.Generators.ActorMethodAttribute` can be used to map interface methods definitions to specific actor methods should the names differ (e.g. the interface uses "Async" suffix common in .NET but the actor methods do not). 1. A strongly-typed client will be generated that can be used to invoke actor methods. ```csharp using Dapr.Actors; using Dapr.Actors.Client; using Sample; var proxy = ActorProxy.Create(ActorId.CreateRandom(), "SampleActor"); using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30)); var client = new SampleActorClient(proxy); var state = await client.GetStateAsync(cancellationTokenSource.Token); await client.SetStateAsync(new SampleState("Hello, World!"), cancellationTokenSource.Token); ``` ## Run the example ### Start the ActorService Change directory to the `ActorService` folder: ```bash cd examples/GeneratedActor/ActorService ``` To start the `ActorService`, execute the following command: ```bash dapr run --app-id generated-service --app-port 5226 -- dotnet run ``` ### Run the ActorClient Change directory to the `ActorClient` folder: ```bash cd examples/GeneratedActor/ActorClient ``` To run the `ActorClient`, execute the following command: ```bash dapr run --app-id generated-client -- dotnet run ``` ### Expected output You should see the following output from the `ActorClient`: ``` == APP == Testing generated client... == APP == Done! ``` You should see also see the following output from the `ActorService`: ``` == APP == info: GeneratedActor.RemoteActor[0] == APP == GetStateAsync called. == APP == info: GeneratedActor.RemoteActor[0] == APP == SetStateAsync called. ```