13

人们在使用 c# 无状态库时如何构造他们的代码?

https://github.com/nblumhardt/stateless

我特别感兴趣的是这如何与注入的依赖关系以及正确的职责方法和正确分层联系在一起。

我目前的结构涉及以下内容:

public class AccountWf
{
    private readonly AspNetUser aspNetUser;

    private enum State { Unverified, VerificationRequestSent, Verfied, Registered }
    private enum Trigger { VerificationRequest, VerificationComplete, RegistrationComplete }

    private readonly StateMachine<State, Trigger> machine;

    public AccountWf(AspNetUser aspNetUser, AccountWfService userAccountWfService)
    {
        this.aspNetUser = aspNetUser;

        if (aspNetUser.WorkflowState == null)
        {
            aspNetUser.WorkflowState = State.Unverified.ToString();
        }

        machine = new StateMachine<State, Trigger>(
        () => (State)Enum.Parse(typeof(State), aspNetUser.WorkflowState),
        s => aspNetUser.WorkflowState = s.ToString()
        );

        machine.Configure(State.Unverified)
        .Permit(Trigger.VerificationRequest, State.VerificationRequestSent);

        machine.Configure(State.VerificationRequestSent)
        .OnEntry(() => userAccountWfService.SendVerificationRequest(aspNetUser))
        .PermitReentry(Trigger.VerificationRequest)
        .Permit(Trigger.VerificationComplete, State.Verfied);

        machine.Configure(State.Verfied)
        .Permit(Trigger.RegistrationComplete, State.Registered);

    }

    public void VerificationRequest()
    {
        machine.Fire(Trigger.VerificationRequest);
    }

    public void VerificationComplete()
    {
        machine.Fire(Trigger.VerificationComplete);
    }

    public void RegistrationComplete()
    {
        machine.Fire(Trigger.RegistrationComplete);
    }

}

我们应该在 OnEntry 钩子内实现所有流程(调用服务),还是在验证状态转换允许发生后在外部实现流程?如果是这样,我想知道如何进行事务管理。

我想我所追求的是那些已经使用无状态实现某些东西以及如何处理代码结构的人的一些最佳指导。

4

1 回答 1

12

在讨论结构本身之前,请注意几点:

  • OnEntry仅当触发器已成功触发时才会执行操作。

  • 在当前状态下不允许触发的触发器将抛出InvalidOperationException. 如果您不希望出现异常,请考虑覆盖OnUnhandledTrigger(我发现记录未处理的触发器是查找逻辑缺陷的好方法)。

OnEntry我对/结构的经验法则OnExit是,将放置任何创建和逻辑OnEntry,并完成任何所需的清理工作OnExit

因此,在您的情况下,鉴于您正在使用注入的依赖项(并假设您没有获得这些依赖项的所有权,即其他人将管理他们的生命周期),您可以将所有逻辑OnEntry.

考虑到这一点,您的状态机当前的结构方式非常好。

最后一点,请记住,从推进状态机和执行状态机逻辑的同一线程中触发触发器可能并且将导致 stackoverflow 异常(请参阅此处了解如何解决自动推进问题)。

于 2014-10-15T09:11:47.397 回答