2016-02-05 6 views
2

я определил следующую государственную машину в Masstransit:Как я могу соотнести события в машине состояния masstransit без использования Guid?

public class OrderStateMachine : MassTransitStateMachine<OrderState> 
{ 
    public OrderStateMachine() 
    { 
     InstanceState(x => x.Status); 

     Event(() => OrderCreated, x => x.CorrelateBy(order => order.OrderCode, ctx => ctx.Message.OrderCode).SelectId(ctx => NewId.NextGuid())); 

     //How should I select an id for these events? 
     Event(() => OrderProvisioned, x => x.CorrelateBy(order => order.OrderCode, ctx => ctx.Message.OrderCode)); 
     Event(() => OrderInvoiced, x => x.CorrelateBy(order => order.OrderCode, ctx => ctx.Message.OrderCode)); 

     State(() => Created); 
     State(() => Finished); 

     CompositeEvent(() => OrderFinished, order => order.CompositeStatus, OrderProvisioned, OrderInvoiced); 

     Initially(
      When(OrderCreated) 
       .Then(context => Console.WriteLine("Order created")) 
       .TransitionTo(Created)); 

     During(Created, 
      When(OrderFinished) 
       .Then(context => Console.WriteLine("Order finished")) 
       .TransitionTo(Finished) 
       .Finalize()); 

    } 

    public State Created { get; set; } 
    public State Finished { get; set; } 

    public Event<OrderCreated> OrderCreated { get; set; } 
    public Event<OrderProvisioned> OrderProvisioned { get; set; } 
    public Event<OrderInvoiced> OrderInvoiced { get; set; } 
    public Event OrderFinished { get; set; } 

} 

public class OrderState : SagaStateMachineInstance 
{ 
    public Guid CorrelationId { get; set; } 

    public string OrderCode { get; set; } 
    public string Status { get; set; } 
    public CompositeEventStatus CompositeStatus { get; set; } 

} 

public class OrderCreated 
{ 
    public string OrderCode { get; set; } 

    public OrderCreated(string orderCode) 
    { 
     OrderCode = orderCode; 
    } 
} 

public class OrderInvoiced 
{ 
    public string OrderCode { get; set; } 

    public OrderInvoiced(string orderCode) 
    { 
     OrderCode = orderCode; 
    } 

} 

public class OrderProvisioned 
{ 
    public string OrderCode { get; set; } 

    public OrderProvisioned(string orderCode) 
    { 
     OrderCode = orderCode; 
    } 
} 

Как я могу соотнести OrderProvisoned и событие OrderInvoiced к тому же OrderState например, в качестве исходного события OrderCreated без отправки Guids в моих событиях и использовать только ordercode свойство их коррелировать? Если я запустил этот пример, я никогда не получаю событие OrderFinished, если отправлены оба OrderProvisioned и OrderInvoiced, но если я добавлю Guids к событиям и скоррелирую их на основе этого Guid, он будет выполнен правильно.

ответ

2

Я решил это, видимо, вы должны явно установить настраиваемый коррелятор в экземпляре statemachine, я бы ожидал, что masstransit сделает это для меня. Так что это адаптированный код исходного состояния:

  Initially(
      When(OrderCreated) 
       .Then(context => context.Instance.OrderCode = context.Data.OrderCode) 
       .Then(context => Console.WriteLine("Order created")) 
       .TransitionTo(Created)); 

Кроме того, используя сагу завод работает, но я думаю, что вы могли бы отказаться от логики selectid как сага завод берет верх, но чем я получаю исключение ,

 Event(() => OrderCreated, 
      x => 
      { 
       x.CorrelateBy(order => order.OrderCode, ctx => ctx.Message.OrderCode); 
       x.InsertOnInitial = true; 
       x.SetSagaFactory(context => new OrderState 
       { 
        CorrelationId = NewId.NextGuid(), 
        OrderCode = context.Message.OrderCode 
       }); 
       x.SelectId(context => NewId.NextGuid()); 
      }); 
+0

FYI, вызов 'x.SelectId (...)' излишний, поскольку 'SetSagaFactory' создает сагу и инициализирует значение. Я должен проверить, но я считаю, что это правильно. –

1

Есть ли сломанный единичный тест, который можно было бы использовать, чтобы узнать, не работает ли это поведение? Из отредактированного кода выше, похоже, я ожидаю, что он будет скоррелирован - с помощью OrderCode. Вот как работает пример корзины покупок.

Функция SelectId() нужна только для события, которое инициирует конечный автомат, так как именно здесь назначается CorrelationId. Если он не используется другими событиями, нет необходимости «выбирать» его, поскольку Query (orderCode) будет выполнять корреляцию.

Вот как корзина пример работает в образце: https://github.com/MassTransit/Sample-ShoppingWeb/blob/master/src/CartTracking/ShoppingCartStateMachine.cs#L15

В вашем примере выше:

Event(() => OrderCreated, x => x.CorrelateBy(order => order.OrderCode, ctx => ctx.Message.OrderCode).SelectId(ctx => NewId.NextGuid())); 

Event(() => OrderProvisioned, x => x.CorrelateBy(order => order.OrderCode, ctx => ctx.Message.OrderCode)); 
Event(() => OrderInvoiced, x => x.CorrelateBy(order => order.OrderCode, ctx => ctx.Message.OrderCode)); 

Это точно, как я хотел бы настроить его, и кажется, что вы на правильный трек.

+0

Я решил это, очевидно, вы должны явно установить пользовательскую корреляцию в экземпляре statemachine, я бы ожидал, что masstransit сделает это для меня. –

 Смежные вопросы

  • Нет связанных вопросов^_^