如何确保在编译时将消息发送到 Akka.net 中的正确 Actor?

How to ensure at compile time that messages are send to the right Actor in Akka.net?

因为 Akka.net 系统 returns 仅引用 (IActorRef) 到 Actor,您只能通过参数不强的 Tell() 和 Ask() 与 Actor 交互typed 并且只是 object base 类型...我脑子里出现了一些问题。

如何确保在编译时 "talking" 是正确的 Actor 类型? (例如,如果您在 class 的构造函数中仅收到 IActorRef 而不是具体的接口合约或通过对 Actor 系统的请求,那么您不知道 Actor 能够处理该消息) 您如何确保 Actor 属于特定类型以及如何知道您正在为该类型选择正确的消息?

尽管松散耦合很好,但它的缺点多于优点 "TellAnything" 对象契约方法(从我的角度来看),Microsoft Orleans Grains 在我看来更适合您有一个明确的接口。我是否错过了 Akka.net 提供的具有严肃合同的功能?

具有显式接口的 Microsoft Orleans:

public interface IHello : Orleans.IGrainWithIntegerKey
{
  Task<string> SayHello(string greeting);
}

public class HelloGrain : Orleans.Grain, IHello
{
  Task<string> SayHello(string greeting)
  {
    return Task.FromResult($"You said: '{greeting}', I say: Hello!");
  }
}

// Get a reference to the IHello grain with id '0'.
var friend = GrainClient.GrainFactory.GetGrain<IHello>(0);

// Send a greeting to the grain and await the response.
Console.WriteLine(await friend.SayHello("Good morning, my friend!"));

Akka.net 仅抱怨 Tell 和 Ask(带对象参数):

Akka.net 中是否有类似的东西允许显式合同?我知道 Java 中有支持 Akka 的代理,但 Akka.net 似乎没有可比性。

MyActorSystem = ActorSystem.Create("MyActorSystem");

// create top-level actors within the actor system
Props consoleWriterProps = Props.Create<ConsoleWriterActor>();
IActorRef consoleWriterActor = MyActorSystem.ActorOf(consoleWriterProps, "consoleWriterActor");

// now you can tell everything to consoleWriterActor at compile time (even though this Actor only understands a specific message)

// begin processing
consoleReaderActor.Tell(ConsoleReaderActor.StartCommand);

如何保证“接口”的客户端只使用正确的命令?

如果 Akka.net 有这样的东西就好了:

Props consoleWriterProps = Props.Create<ConsoleWriterActor>();
IConsoleWriter consoleWriterActor = MyActorSystem.ActorOf<IConsoleWriter>(consoleWriterProps, "consoleWriterActor");

consoleReaderActor.MyExplicitCallThatAllowsOnlyStartCommandType(ConsoleReaderActor.StartCommand);

您可以通过 Akka.Interfaced 使用接口契约,但这会引入下一级的复杂性和间接性,这可能会导致性能下降,阻止一些更高级的消息传递模式和 actors 中的动态行为切换。

其他方法是用它的类型化版本包装 IActorRef,以确保只有特定类型的消息可以通过 Tell 方法传递 - 这正是 Akkling 的工作方式。