简体   繁体   中英

Publish message in Saga where type is known only runtime

I want to publish a message from a Saga where the messgae type is not known compile time, only runtime. So far i've only found methods for publishing a message with generic signature - i cannot find any where i can publish a runtime type.

I'm in the works of modifying the Sample-Batch application https://github.com/MassTransit/Sample-Batch to be able to batch any message type

How Sample-Batch is configured

Initially(
    When(BatchJobReceived)
        .Then(context => Touch(context.Saga, context.Message.Timestamp))
        .Then(context => SetReceiveTimestamp(context.Saga, context.Message.Timestamp))
        .Then(Initialize)
        .PublishAsync(context => context.Init<ProcessBatchJob>(new
        {
            BatchJobId = context.Saga.CorrelationId,
            InVar.Timestamp,
            context.Saga.BatchId,
            context.Saga.OrderId,
            context.Saga.Action
        }))
        .TransitionTo(Received));

What i want to accomplish

  1. Receive the BatchJobReceived message
  2. Deserialize the inner message Json using InnerMessageAsString and InnerMessageType
  3. Store the inner message on the state
  4. Publish the inner message And then keep state of the messages when they return
Initially(
    When(BatchJobReceived)
        .Then(context => Touch(context.Saga, context.Message.Timestamp))
        .Then(context => SetReceiveTimestamp(context.Saga, context.Message.Timestamp))
        .Then(Initialize)
        .Then(context => DeserializeInnerMessage(context.Saga, context.Message))
        .PublishAsync(context => context.Init(context.Saga.InnerMessage, context.Saga.InnerMessageType))
        .TransitionTo(Received));
static void DeserializeInnerMessage(BatchJobState state, BatchJobReceived job)
{
    var innerMessageType = Type.GetType(job.InnerMessageType);
    var innerMessage = JsonConvert.DeserializeObject(job.InnerMessageAsString, innerMessageType);

    state.InnerMessage = innerMessage;
}

There are however no context.Init() methods taking a Type parameter, it solely have a generic signature context.Init<>() .

How do i accomplish this? Or any other approaches more suitable?

There isn't one, you can use your own ThenAsync statement to publish an unknown type as object :

.ThenAsync(x => x.Publish(x.Saga.InnerMessage, x.Saga.InnerMessageType)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM