2014-06-26 47 views
1

我一直在使用MassTransit自動加密狀態機。我很喜歡與那個狀態/傳奇機器一起工作,特別是它如何配置和設置,以及我可以爲狀態機提供實現契約的事件作爲消息。在.net中持久存儲的佐賀實現。替代Masstransit Saga?

這是怎麼能是這樣的:

//define the statemachine with a State class (ServiceState) 
public class ServiceStateMachine : 
    AutomatonymousStateMachine<ServiceState>{ 

    //define available states 
    public State Available { get; set; } 
    public State WaitForItem { get; set; } 

    //define available events 
    public Event<RequestItem> RequestItem { get; set; } 

    //configure the state machine and configure the store to use the ServiceState class 
    public void ConfigureStateMachineCorrelations(StateMachineSagaRepositoryConfigurator<ServiceState> r) 

    //bind events to contracts and conditions 
    r.Correlate(RequestItem, 
      (state, message) => 
       state.CorrelationId == message.CorrelationId) 
    } 


    public ServiceStateMachine(IStateMachineActivityFactory activityFactory 
    { 
     State(() => Available); 
     State(() => WaitForItem); 

     Event(() => RequestItem); 

     //bind states, events, activities, custom actions...    
     During(Available, 
      When(RequestItem) 
       .Then((state, message) => 
       { 
        state.ServiceId = message.ServiceId; // just an example baby! 
       }) 
       .TransitionTo(WaitForItem) 
       .Then(() => _activityFactory.GetActivity<RequestItemActivity, ServiceState>()) 
    } 

是什麼樣的替代佐賀實現那裏都差不多,但沒有連接到MQ架構?我想我真正想要的是至少有一個內存持久存儲的狀態機或佐賀實現。

+0

您可以自行使用自動密碼,與MassTransit完全分離。實際上,NHibernate集成也是一個單獨的庫。 –

+0

@ChrisPatterson你能用一個例子回答這個問題嗎?我有或多或少與OP相同的問題,但很難找到完整的持久性示例。謝謝! – Anttu

回答

1

您可以使用自動密碼完全獨立於MassTransit(或任何消息系統)。有或沒有數據的方法(和提升函數來分解狀態機或事件)用於引發事件。

_machine.RaiseEvent(instance, x => x.RequestItem, itemData); 

普通狀態機和實例實現沒有狀態(實例)存儲的概念,這取決於應用程序。例如,你可以在內存中鍵入一個字典,或者你可以使用NHibernate程序集,它可以很容易地將狀態實例保存到SQL數據庫中(該程序集主要包括用於映射CurrentState屬性的助手以及其他一些自定義類型

這是在網上被要求這樣的例子,我最近寫爲Automatonymous的最新分支(MT3)一個單元測試:

class PhoneStateMachine : 
    AutomatonymousStateMachine<PrincessModelTelephone> 
{ 
    public PhoneStateMachine() 
    { 
     InstanceState(x => x.CurrentState); 

     State(() => OffHook); 
     State(() => Ringing); 
     State(() => Connected); 
     State(() => OnHold, Connected); 
     State(() => PhoneDestroyed); 

     Event(() => ServiceEstablished); 
     Event(() => CallDialed); 
     Event(() => HungUp); 
     Event(() => CallConnected); 
     Event(() => LeftMessage); 
     Event(() => PlacedOnHold); 
     Event(() => TakenOffHold); 
     Event(() => PhoneHurledAgainstWall); 

     Initially(
      When(ServiceEstablished) 
       .Then(context => context.Instance.Number = context.Data.Digits) 
       .TransitionTo(OffHook)); 

     During(OffHook, 
      When(CallDialed) 
       .TransitionTo(Ringing)); 

     During(Ringing, 
      When(HungUp) 
       .TransitionTo(OffHook), 
      When(CallConnected) 
       .TransitionTo(Connected)); 

     During(Connected, 
      When(LeftMessage).TransitionTo(OffHook), 
      When(HungUp).TransitionTo(OffHook), 
      When(PlacedOnHold).TransitionTo(OnHold)); 

     During(OnHold, 
      When(TakenOffHold).TransitionTo(Connected), 
      When(PhoneHurledAgainstWall).TransitionTo(PhoneDestroyed)); 

     DuringAny(
      When(Connected.Enter) 
       .Then(context => StartCallTimer(context.Instance)), 
      When(Connected.Leave) 
       .Then(context => StopCallTimer(context.Instance))); 
    } 


    public State OffHook { get; set; } 
    public State Ringing { get; set; } 
    public State Connected { get; set; } 
    public State OnHold { get; set; } 
    public State PhoneDestroyed { get; set; } 

    public Event<PhoneServiceEstablished> ServiceEstablished { get; set; } 
    public Event CallDialed { get; set; } 
    public Event HungUp { get; set; } 
    public Event CallConnected { get; set; } 
    public Event LeftMessage { get; set; } 
    public Event PlacedOnHold { get; set; } 
    public Event TakenOffHold { get; set; } 
    public Event PhoneHurledAgainstWall { get; set; } 

    void StopCallTimer(PrincessModelTelephone instance) 
    { 
     instance.CallTimer.Stop(); 
    } 

    void StartCallTimer(PrincessModelTelephone instance) 
    { 
     instance.CallTimer.Start(); 
    } 
} 

它被創建和被稱爲(公主模型是如下圖所示:

var phone = new PrincessModelTelephone(); 
await _machine.RaiseEvent(phone, _machine.ServiceEstablished, new PhoneServiceEstablished {Digits = "555-1212"}); 

await _machine.RaiseEvent(phone, x => x.CallDialed); 
await _machine.RaiseEvent(phone, x => x.CallConnected); 
await _machine.RaiseEvent(phone, x => x.PlacedOnHold); 

await Task.Delay(10); 

await _machine.RaiseEvent(phone, x => x.HungUp); 

我確定有更多的例子,但是狀態機與任何依賴關係都是分開的,使得它可以在任何地方使用。

相關問題