5

我在 Masstransit 中定义了以下状态机:

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 事件关联到与初始 OrderCreated 事件相同的 OrderState 实例,而不在我的事件中发送 Guid 并且只使用 ordercode 属性来关联它们?如果我运行此示例,如果同时发送了 OrderProvisioned 和 OrderInvoiced,我永远不会收到 OrderFinished 事件,但是如果我将 Guid 添加到事件中并根据该 Guid 关联它们,它就会正确执行。

4

2 回答 2

4

我解决了它,显然你必须在状态机实例上明确设置自定义相关 ID,我希望公共交通会为我做到这一点。所以这是初始状态的改编代码:

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

也可以使用 saga 工厂,但我认为你可以放弃 selectid 逻辑,因为 saga 工厂会否决这一点,但我得到了一个例外。

        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());
            });
于 2016-02-11T08:09:30.477 回答
1

是否有损坏的单元测试可用于查看此行为是否不起作用?从上面编辑过的代码来看,这似乎是我期望的关联方式——使用 OrderCode。这也是购物车示例的工作原理。

只有启动状态机的事件才需要 SelectId() 函数,因为这是分配 CorrelationId 的地方。如果其他事件不使用它,则无需“选择”它,因为查询(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));

这正是我将如何配置它,看起来你在正确的轨道上。

于 2016-02-05T18:18:18.430 回答