Workflow Design Dilemma - State Machine, yes or no

前端 未结 9 1839
清歌不尽
清歌不尽 2020-12-03 05:38

I\'m a beginner with WF, but I\'ve read a book and done a lot of googling. I want to write an inventory management service. The inventory is made up of individual items whic

相关标签:
9条回答
  • 2020-12-03 06:18

    Aviad, I agree with your comment that the workflow should be between states. The states of the parts being inventoried sounds like a status/property of the item. That status can be stored in nearly any manner (e.g. database, file...) because the movement of the item between states would live in the business logic layer.

    Sounds like a fun project, good luck.

    0 讨论(0)
  • 2020-12-03 06:21

    A state machine is a very powerful technique to implement, although I would recommend that you consider a framework called StateLess by Nicholas Blumhardt (Autofaq creator), as it is an amazingly simple implementation of a state machine that avoids the unnecessary complexity of Windows Workflow. His approach avoids the issue of long running workflows being held by a runtime engine, as the state is defined by a simple variable such as a string or int.

    Here is a sample state machine:

    var phoneCall = new StateMachine<State, Trigger>(State.OffHook);
    
    phoneCall.Configure(State.OffHook)
        .Permit(Trigger.CallDialed, State.Ringing);
    
    phoneCall.Configure(State.Ringing)
        .Permit(Trigger.HungUp, State.OffHook)
        .Permit(Trigger.CallConnected, State.Connected);
    
    phoneCall.Configure(State.Connected)
        .OnEntry(() => StartCallTimer())
        .OnExit(() => StopCallTimer())
        .Permit(Trigger.LeftMessage, State.OffHook)
        .Permit(Trigger.HungUp, State.OffHook)
        .Permit(Trigger.PlacedOnHold, State.OnHold);
    
    // ...
    
    phoneCall.Fire(Trigger.CallDialled);
    Assert.AreEqual(State.Ringing, phoneCall.State);
    

    Your state can be an integer which will allow you to feed it the current state from a database. This can be set on the constructor of the state machine as follows:

    var stateMachine = new StateMachine<State, Trigger>(
        () => myState.Value,
        s => myState.Value = s);
    

    You can implement this in just one assembly, compared to the multiple projects you need to run Windows Workflow. Maintenance is extremely low, their is no "designer" that generates code for your, etc. Again, it is simple, and there lies the beauty.

    0 讨论(0)
  • 2020-12-03 06:21

    Even though the state-machine pattern is technically the correct option, there's also an option to create a sequential workflow with one giant loop. In some cases, it actually works better and is more understandable.

    0 讨论(0)
提交回复
热议问题