2012-11-12 17 views
8

bbv.Common.StateMachineクラスは私が今まで見た中で最高の状態マシンコードです。しかし、ただ一つのことが欠けています:現在の状態を得ること。あなたはそれが簡単に動作を確認することができますbbv.Common.StateMachine(現在はAppccelerate.StateMachine)クラスから現在の状態を取得する方法は?

fsm = new ActiveStateMachine<States, Events>(); 

     fsm.In(States.OrderCreated) 
      .On(Events.Submitted) 
      .Goto(States.WaitingForApproval); 
     fsm.In(States.WaitingForApproval) 
      .On(Events.Reject) 
      .Goto(States.Rejected); 
     fsm.In(States.WaitingForApproval) 
      .On(Events.Approve) 
      .Goto(States.BeingProcessed); 
     fsm.In(States.BeingProcessed) 
      .On(Events.ProcessFinished) 
      .Goto(States.SentByMail); 
     fsm.In(States.SentByMail) 
      .On(Events.Deliver) 
      .Goto(States.Delivered); 

     fsm.Initialize(States.OrderCreated); 
     fsm.Start(); 
     fsm.Fire(Events.Submitted); 
     // Save this state to database 

これは、注文追跡システムです。

しかし、データベースの注文状態を保存します。だから私はどの状態が命令であるかを示すことができるだろう。

私は

fsm.GetCurrentState() 
//show this state in the a table 

方法を必要としています。実際には方法があります:ExecuteOnEntryを使用して、すべての州のエントリのローカル値を変更することができます。しかし、私は自分自身を繰り返すので、すべての州のためにExecuteOnEntryを書くのは面倒です!

これを行うには繊細な方法が必要です。

+1

がやった、それに答えるようにするために、それは簡単ですあなたはbbv.CommonがAppccelerateに改名されたことを知っています。私たちの新しいホームページhttp://www.appccelerate.com –

答えて

13

ダニエルが説明したように、これは仕様です。理由を説明しましょう:

ステートマシンはイベントのキューイングを許可します。したがって、現在の状態についてステートマシンに尋ねると、誤解を招く可能性があります。現在状態Aにありますが、すでに状態Bに入るイベントが待ち受けています。

さらに、私は状態機械の内部状態(あなたが使用している状態ステートマシンの外部ステート(データベース内で永続化したいステートマシンステート)で直接ステートマシンの定義を行うことができます。これら2つを直接結合すると、外部(あなたの場合はデータベース)に影響を与えずにステートマシンを内部的にリファクタリングする能力が失われます。状態AをA1とA2に分けなければならないシナリオに頻繁に遭遇します。なぜなら、異なるアクションをアタッチする必要があるからですが、依然として環境と同じ状態を表しています。 したがって、OnEntryExecute()を使用して記述したか、またはマッピングを提供し、拡張機能を使用して、内部状態と外部状態を分離することを強くお勧めします。あなたはこのように、状態マシンに拡張子を追加することができます

public class CurrentStateExtension : ExtensionBase<State, Event> 
{ 
    public State CurrentState { get; private set; } 

    public override void SwitchedState(
     IStateMachineInformation<State, Event> stateMachine, 
     IState<State, Event> oldState, 
     IState<State, Event> newState) 
    { 
     this.CurrentState = newState.Id; 
    } 
} 

:あなたがアクセスを得るために、直接この拡張機能を使用することができます。もちろん、

currentStateExtension = new CurrentStateExtension(); 
machine.AddExtension(currentStateExtension); 

これはあなたの現在の状態を取得する拡張機能です現在の状態にも移行します。 さらに簡単にするには、ステートマシンを定義するクラスに拡張機能を実装させ、拡張機能として渡します。余分なクラスを取り除きましょう。

最後のノート:(それは今と呼ばれているとして、あるいはAppccelerate)あなたはhttps://groups.google.com/forum/?fromgroups#!forum/appccelerateでGoogleのグループにbbv.Commonについての質問をしたときに、私は、質問を見つけて、;-)

+0

をチェックしてくださいありがとう、私はできるだけ早くそれを試してみます。 –

4

これは仕様です。ステートマシンの状態をデザインのにおいとして照会することを検討します。もちろん例外的なケースがあります。次の2つのオプションがあります。

  1. 注文の状態を保存するには、ExecuteOnEntryメソッドを使用します。これは、あなたがビジネスロジックにステートマシンの状態を漏らすことを望んでいないので、行く方法を反映しています。
  2. 内部でStateMachine<TState, TEvent>を使用する独自のステートマシンデコレータを作成します。これは状態を公開します。

ダニエル

関連する問題