什么是标准的Akka.Net消息命令验证模式

本文关键字:消息 命令 验证 模式 Net Akka 标准 什么 | 更新日期: 2023-09-27 18:13:42

我们的许多消息在安全处理之前都需要验证。检查输入,有时应用复杂的业务规则。

在Akka之前的设计中,我将有一个具有单一方法IsValid和错误属性的ICommandValidator<T>。因此,具体的验证将告诉您消息是否有效,如果不是,则可以读取错误。

Akka

。Net我开始为每个消息编写具体的Validator actor(显然创建更多的actor是好的)-例如,CreateTenantCommand由TenantCreatorActor(继承自ReceiveActor)发送给CreateTenantCommandValidatorActor进行验证。如果它是有效的,CreateTenantCommandValidated消息(基本上是包装好的原始消息)被发送给TenantCreateActor,它将打开消息,然后处理消息。

我想知道我是否应该将未经验证的消息列表与需要验证的参与者存储在一起,然后将这些消息与验证响应相关联,或者我应该将整个消息来回发送以进行验证?验证器需要整个消息进行验证,但我不确定在请求参与者上保持消息完整并仅确认其有效性的好处是什么?

在Akka中使用泛型是否常见?网络消息和演员?这似乎是一个包含大量样板文件的领域,但我从来没有在任何例子中看到过很多泛型,所以这让我很担心。我有一个设计,看起来像:

public class IsValidCommand<TCommamd>{
    public TCommamd Command { get; private set; }
    Ctor....
}
public class ValidCommand<TCommamd>
{
    public TCommamd Command { get; private set; }
    Ctor....
}
public class InvalidCommand<TCommamd>
{
    public TCommamd Command { get; private set; }
    public List<string> Errors { get; private set; }
    Ctor....
}    

另一种方法是创建一个组合的ValidatedCommand<T>

public class ValidatedCommand<T>
{
    public T Command { get; set; }
    public IEnumerable<string> Errors { get; }
    public bool IsValid => !Errors.Any();
    Ctor...
}
然后,我可以创建一个泛型ValidatorActor,并向其中注入一个验证器类。例如
var createValidatorProps = Props.Create(() => new ValidatorActor<CreateInstanceCommand>(Self, new CreateInstanceCommandValidator()));
CreateInstanceCommandValidatorActor = Context.ActorOf(createValidatorProps, "CreateInstanceCommandValidatorActor");

与泛型验证器参与者,如:

public class ValidatorActor<T> : ReceiveActor{
    public IActorRef Requestor { get; }
    public ValidatorActor(IActorRef requestor, ICommandValidator<T> validator)
    {
        Requestor = requestor;
        Receive<IsValidCommand<T>>(
            commandWrapper =>
                {
                    var command = commandWrapper.Command;
                    if (validator.Validate(command))
                    {
                        requestor.Tell(new ValidCommand<T>(command));
                    }
                    else
                    {
                        requestor.Tell(new InvalidCommand<T>(command));
                    }
                });
    }
}

可能应该注意,我意识到它可能应该是ValidateAsync,然后PipeTo,所以演员不会阻塞。所以这可能需要ValidatedCommand<T>方法从ValidateAsync方法返回

这意味着这些消息可以标准化。这是在Akka中处理消息验证的合适方法吗?还是我都搞错了?

什么是标准的Akka.Net消息命令验证模式

我的话不是真理,我只是另一个黑客,我只是在给那些权威人士提供我的黑客意见。

我们正在传递消息。理想情况下,你希望所有东西都保持小。但是,在本地系统上,事情也不会序列化,你不必担心(我对此有99.9%的把握)。在远程边界上,我认为你的担忧是合理的。

然而,这是一个过早的优化问题吗?用一种方法,如果有问题,那就分析一下,然后再决定。

re generics,是的,我发现了一些非常好的用途。很普通,其实不是。但在我看来,当它在合适的地方发挥作用时,它是优雅的。当我发现它有效时,我真的很兴奋。

但这可能不是一个充分的答案。

已经使用了类似的模式来观察回调,但也用于验证,当我想写真正通用的代理像演员(例如保证消息传递)