在.NET SDK中运行和使用 virtual actors 的例子。

    通过Dapr actor 程序包,您可以与.NET应用程序中的Dapr虚拟actor进行交互。

    概述

    本文档描述了如何创建一个Actor() 并从客户端程序调用其方法。

    • 接口项目(\MyActor\MyActor.Interfaces). 该项目包含了actor的接口定义。 Actor接口可以在任何项目中以任意的名称定义。 它定义了actor的实现和调用actor的客户端之间的约定。 由于客户端项目可能会依赖它,所以在一个和actor实现分隔开的程序集中定义通常是有意义的。

    • Actor服务项目 (\MyActor\MyActorService)。 该项目实现了Asp.Net Core web service,用于托管actor。 它包含了actor的实现,MyActor.cs。 Actor的实现是一个继承了基类Actor并且实现了Myactor.Interfaces项目中定义的接口的类。 Actor还必须提供接受一个ActorService实例和ActorId的构造函数,并将他们传递给基类。

    • [Actor(TypeName = “MyCustomActorTypeName”)] internal class MyActor : Actor, IMyActor { // … }

    由于我们将创建3个项目,所以选择一个空的目录开始,在你选择的终端中打开它。

    第 1 步:创建 actor 接口

    Actor接口定义了actor的实现和调用actor的客户端之间的约定。

    Actor接口的定义需要满足以下要求:

    • Actor接口必须继承 Dapr.Actors.IActor 接口
    • Actor方法的返回值必须是Task 或者 Task<object>类型
    • Actor方法最多只能有一个参数
    1. # 创建 Actor 接口
    2. dotnet new classlib -o MyActor.Interfaces
    3. cd MyActor.Interfaces
    4. # 添加 Dapr.Actors nuget 包。 请使用来自 nuget.org 的最新软件包版本
    5. dotnet add package Dapr.Actors -v 1.0.0
    6. cd ..

    定义IMyActor接口

    定义 IMyActor 接口和 MyData 数据对象。 在 Myactor.Interface 项目中,将以下代码粘贴到 Myactor.cs 中。

    1. using Dapr.Actors;
    2. using System.Threading.Tasks;
    3. namespace MyActor.Interfaces
    4. {
    5. public interface IMyActor : IActor
    6. {
    7. Task<string> SetDataAsync(MyData data);
    8. Task<MyData> GetDataAsync();
    9. Task RegisterReminder();
    10. Task UnregisterReminder();
    11. Task RegisterTimer();
    12. Task UnregisterTimer();
    13. }
    14. public class MyData
    15. {
    16. public string PropertyA { get; set; }
    17. public string PropertyB { get; set; }
    18. public override string ToString()
    19. {
    20. var propAValue = this.PropertyA == null ? "null" : this.PropertyA;
    21. var propBValue = this.PropertyB == null ? "null" : this.PropertyB;
    22. return $"PropertyA: {propAValue}, PropertyB: {propBValue}";
    23. }
    24. }
    25. } "null" : this.PropertyA;
    26. var propBValue = this.PropertyB == null ? "null" : this.PropertyB;
    27. return $"PropertyA: {propAValue}, PropertyB: {propBValue}";
    28. }
    29. }
    30. }
    1. # 创建 ASP.Net Web 服务来托管 Dapr actor
    2. dotnet new web -o MyActorService
    3. cd MyActorService
    4. # 添加 Dapr.Actors.AspNetCore nuget 包. 请从nuget.org添加最新的包版本
    5. dotnet add package Dapr.Actors.AspNetCore -v 1.0.0
    6. # 添加 Actor 接口引用
    7. dotnet add reference ../MyActor.Interfaces/MyActor.Interfaces.csproj
    8. cd ..

    添加 actor 实现

    实现IMyActor接口并继承自 Dapr.Actors.Actor 。 下面的例子同样展示了如何使用Actor Reminders。 Actor如果要使用Reminders,则必须实现IRemindable接口 如果你不打算使用Reminder功能,你可以跳过下面代码中实现IRemindable接口和Reminder特定方法的操作。

    MyActorService 项目中,将以下代码粘贴到 MyActor.cs 中。

    Actor runtime 使用 ASP.NET Core Startup.cs 来配置。

    运行时使用ASP.NET Core依赖注入系统来注册actor类型和基本服务。 通过在 ConfigureServices(...) 中调用 AddActors(...) 方法来提供这种集成。 使用传递到 AddActors(...) 方法的委托来注册actor类型并配置actor运行时设置。 你可以在中为依赖注入注册额外的类型。 它们都可以被注入到你的Actor类型的构造器。

    Actors通过Dapr runtime使用HTTP调用来实现。 此功能是应用程序的 HTTP 处理管道的一部分,在 Configure(...) 方法中的UseEndpoint(...) 注册。

    MyActorService 项目中,将以下代码粘贴到 Startup.cs 中。

    1. using Microsoft.AspNetCore.Builder;
    2. using Microsoft.AspNetCore.Hosting;
    3. using Microsoft.Extensions.DependencyInjection;
    4. using Microsoft.Extensions.Hosting;
    5. namespace MyActorService
    6. {
    7. public class Startup
    8. {
    9. public void ConfigureServices(IServiceCollection services)
    10. {
    11. services.AddActors(options =>
    12. {
    13. // Register actor types and configure actor settings
    14. options.Actors.RegisterActor<MyActor>();
    15. });
    16. }
    17. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    18. {
    19. if (env.IsDevelopment())
    20. {
    21. app.UseDeveloperExceptionPage();
    22. }
    23. app.UseHttpsRedirection();
    24. app.UseRouting();
    25. app.UseEndpoints(endpoints =>
    26. {
    27. // Register actors handlers that interface with the Dapr runtime.
    28. endpoints.MapActorsHandlers();
    29. });
    30. }
    31. }
    32. }

    第 3 步:添加客户端

    创建一个简单的控制台应用来调用actor服务。 Dapr SDK 提供 Actor 代理客户端来调用Actor接口中定义的actor方法。

    创建 actor 客户端项目并添加依赖

    1. # 创建 Actor 客户端
    2. dotnet new console -o MyActorClient
    3. cd MyActorClient
    4. # 添加 Dapr.Actors nuget 包。 Please use the latest package version from nuget.org
    5. 请从nuget.org添加最新的包版本
    6. dotnet add package Dapr.Actors -v 1.0.0
    7. # 添加 Actor 接口引用
    8. dotnet add reference ../MyActor.Interfaces/MyActor.Interfaces.csproj
    9. cd ..

    您可以使用 ActorProxy.Create<IMyActor>(.) 来创建一个强类型客户端,并调用 actor 上的方法。

    MyActorClient 项目中,将以下代码粘贴到 Program.cs 中。

    1. using System;
    2. using System.Threading.Tasks;
    3. using Dapr.Actors;
    4. using Dapr.Actors.Client;
    5. using MyActor.Interfaces;
    6. namespace MyActorClient
    7. {
    8. class Program
    9. static async Task MainAsync(string[] args)
    10. {
    11. // Registered Actor Type in Actor Service
    12. var actorType = "MyActor";
    13. // An ActorId uniquely identifies an actor instance
    14. // If the actor matching this id does not exist, it will be created
    15. var actorId = new ActorId("1");
    16. // Create the local proxy by using the same interface that the service implements.
    17. //
    18. // You need to provide the type and id so the actor can be located.
    19. var proxy = ActorProxy.Create<IMyActor>(actorId, actorType);
    20. // Now you can use the actor interface to call the actor's methods.
    21. Console.WriteLine($"Calling SetDataAsync on {actorType}:{actorId}...");
    22. var response = await proxy.SetDataAsync(new MyData()
    23. {
    24. PropertyA = "ValueA",
    25. PropertyB = "ValueB",
    26. });
    27. Console.WriteLine($"Got response: {response}");
    28. Console.WriteLine($"Calling GetDataAsync on {actorType}:{actorId}...");
    29. var savedData = await proxy.GetDataAsync();
    30. Console.WriteLine($"Got response: {response}");
    31. }
    32. }
    33. }
    34. var proxy = ActorProxy.Create<IMyActor>(actorId, actorType);
    35. // Now you can use the actor interface to call the actor's methods.
    1. 运行 MyActorService

      由于MyActorService正在托管 Actors,因此需要使用 Dapr CLI 来运行。

      您将在这个终端中看到 daprdMyActorService 的命令行输出。 您应该看到以下情况,这表明应用程序已成功启动。

      1. ...
      2. ℹ️ Updating metadata for app command: dotnet run
      3. You're up and running!
      4. == APP == info: Microsoft.Hosting.Lifetime[0]
      5. == APP == Now listening on: https://localhost:5001
      6. == APP == info: Microsoft.Hosting.Lifetime[0]
      7. == APP == Now listening on: http://localhost:5000
      8. == APP == info: Microsoft.Hosting.Lifetime[0]
      9. == APP == Application started. Press Ctrl+C to shut down.
      10. == APP == info: Microsoft.Hosting.Lifetime[0]
      11. == APP == Hosting environment: Development
      12. == APP == info: Microsoft.Hosting.Lifetime[0]
      13. == APP == Content root path: /Users/ryan/actortest/MyActorService
    2. 运行 MyActorClient

      MyActorClient 作为客户端,它可以用 dotnet run 正常运行。

      打开一个新的终端,导航到 MyActorClient 目录。 然后运行此项目:

      1. dotnet run

      您应该看到命令行输出,如:

      1. Startup up...
      2. Calling SetDataAsync on MyActor:1...
      3. Got response: Success
      4. Calling GetDataAsync on MyActor:1...
      5. Got response: Success

    现在您已经成功创建了 actor 服务和客户端。 查看相关链接部分了解更多信息。

    相关链接