不可能有两个处理相同消息类型的传奇

发布于 2024-10-08 14:42:55 字数 3509 浏览 1 评论 0原文

我有 2 个不同的传奇(我的意思是传奇类型)处理相同的消息。

     public class AttachMessageToBugSaga : TpSaga<AttachMessageToBugSagaData>, IAmStartedByMessages<MessageIsNotAttached>, IHandleMessages<MessageAttachedToGeneralMessage>
    {
        public override void ConfigureHowToFindSaga()
        {
            ConfigureMapping<MessageAttachedToGeneralMessage>(
             saga => saga.Id,
             message => message.SagaId
             );
        }
        public void Handle(MessageIsNotAttachedToBug message)
        {
            Send(new AttachMessageToGeneralCommand { MessageId = 66, GeneralId = 13 });
        }

        public void Handle(MessageAttachedToGeneralMessage message)
        {
            //do some stuf fhere
        }
    }

    public class AttachMessageToBugSagaData : IContainSagaData
    {
        public Guid Id { get; set; }
        public string Originator { get; set; }
        public string OriginalMessageId { get; set; }
    }

    public class AttachMessageToRequestSaga : TpSaga<AttachMessageToRequestSagaData>, IAmStartedByMessages<MessageIsNotAttachedToRequest>, IHandleMessages<MessageAttachedToGeneralMessage>
    {
        public override void ConfigureHowToFindSaga()
        {
            ConfigureMapping<MessageAttachedToGeneralMessage>(
             saga => saga.Id,
             message => message.SagaId
             );
        }

        public void Handle(MessageIsNotAttachedMessageToRequest message)
        {
            //do some stuff here
        }

        public void Handle(MessageAttachedToGeneralMessage message)
        {
            //do some stuff here
        }
    }

    public class AttachMessageToRequestSagaData : IContainSagaData
    {
        public Guid Id { get; set; }
        public string Originator { get; set; }
        public string OriginalMessageId { get; set; }
    }

当我运行示例时,出现异常:

System.InvalidCastException:无法将类型为“MyCustomPlugin.AttachMessageToGeneralSagaData”的对象转换为类型“MyCustomPlugin.AttachMessageToRequestSagaData”。

我明白为什么会发生这种情况,但我仍然需要一些解决方法。我尝试实现我自己的 IFindSagas 类:

public class SagaFinder : IFindSagas<AttachMessageToGeneralSagaData>.Using<MessageAttachedToGeneralMessage>,
IFindSagas<AttachMessageToRequestSagaData>.Using<MessageAttachedToGeneralMessage>,
IFindSagas<AttachMessageToRequestSagaData>.Using<MessageIsNotAttachedToRequest>,
IFindSagas<AttachMessageToRequestSagaData>.Using<MessageIsNotAttachedToBug>
{
    AttachMessageToGeneralSagaData IFindSagas<AttachMessageToGeneralSagaData>.Using<MessageAttachedToGeneralMessage>.FindBy(MessageAttachedToGeneralMessage message)
    {
        return ObjectFactory.GetInstance<AttachMessageToGeneralSagaData>();
    }

    AttachMessageToRequestSagaData IFindSagas<AttachMessageToRequestSagaData>.Using<MessageAttachedToGeneralMessage>.FindBy(MessageAttachedToGeneralMessage message)
    {
        return ObjectFactory.GetInstance<AttachMessageToRequestSagaData>();
    }

    public AttachMessageToRequestSagaData FindBy(MessageIsNotAttachedToRequest message)
    {
        return new AttachMessageToRequestSagaData();
    }

    public AttachMessageToRequestSagaData FindBy(MessageIsNotAttachedToBug message)
    {
        return new AttachMessageToRequestSagaData();
    }
}

但我没有进入“MessageAttachedToGeneralMessage”的查找器。 请告诉我是否还有其他解决方法,或者如何使该示例正常工作。

I have 2 different sagas (I mean saga types) that handle the same message.

     public class AttachMessageToBugSaga : TpSaga<AttachMessageToBugSagaData>, IAmStartedByMessages<MessageIsNotAttached>, IHandleMessages<MessageAttachedToGeneralMessage>
    {
        public override void ConfigureHowToFindSaga()
        {
            ConfigureMapping<MessageAttachedToGeneralMessage>(
             saga => saga.Id,
             message => message.SagaId
             );
        }
        public void Handle(MessageIsNotAttachedToBug message)
        {
            Send(new AttachMessageToGeneralCommand { MessageId = 66, GeneralId = 13 });
        }

        public void Handle(MessageAttachedToGeneralMessage message)
        {
            //do some stuf fhere
        }
    }

    public class AttachMessageToBugSagaData : IContainSagaData
    {
        public Guid Id { get; set; }
        public string Originator { get; set; }
        public string OriginalMessageId { get; set; }
    }

    public class AttachMessageToRequestSaga : TpSaga<AttachMessageToRequestSagaData>, IAmStartedByMessages<MessageIsNotAttachedToRequest>, IHandleMessages<MessageAttachedToGeneralMessage>
    {
        public override void ConfigureHowToFindSaga()
        {
            ConfigureMapping<MessageAttachedToGeneralMessage>(
             saga => saga.Id,
             message => message.SagaId
             );
        }

        public void Handle(MessageIsNotAttachedMessageToRequest message)
        {
            //do some stuff here
        }

        public void Handle(MessageAttachedToGeneralMessage message)
        {
            //do some stuff here
        }
    }

    public class AttachMessageToRequestSagaData : IContainSagaData
    {
        public Guid Id { get; set; }
        public string Originator { get; set; }
        public string OriginalMessageId { get; set; }
    }

When I run the sample I get an exception :

System.InvalidCastException: Unable to cast object of type 'MyCustomPlugin.AttachMessageToGeneralSagaData' to type 'MyCustomPlugin.AttachMessageToRequestSagaData'.

I understand why it happens, but I still need some workaround. I tried to implement my own IFindSagas class :

public class SagaFinder : IFindSagas<AttachMessageToGeneralSagaData>.Using<MessageAttachedToGeneralMessage>,
IFindSagas<AttachMessageToRequestSagaData>.Using<MessageAttachedToGeneralMessage>,
IFindSagas<AttachMessageToRequestSagaData>.Using<MessageIsNotAttachedToRequest>,
IFindSagas<AttachMessageToRequestSagaData>.Using<MessageIsNotAttachedToBug>
{
    AttachMessageToGeneralSagaData IFindSagas<AttachMessageToGeneralSagaData>.Using<MessageAttachedToGeneralMessage>.FindBy(MessageAttachedToGeneralMessage message)
    {
        return ObjectFactory.GetInstance<AttachMessageToGeneralSagaData>();
    }

    AttachMessageToRequestSagaData IFindSagas<AttachMessageToRequestSagaData>.Using<MessageAttachedToGeneralMessage>.FindBy(MessageAttachedToGeneralMessage message)
    {
        return ObjectFactory.GetInstance<AttachMessageToRequestSagaData>();
    }

    public AttachMessageToRequestSagaData FindBy(MessageIsNotAttachedToRequest message)
    {
        return new AttachMessageToRequestSagaData();
    }

    public AttachMessageToRequestSagaData FindBy(MessageIsNotAttachedToBug message)
    {
        return new AttachMessageToRequestSagaData();
    }
}

But I do not get into my finders for "MessageAttachedToGeneralMessage".
Please tell me if there is some other workaround, or how to make this example working.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岁月如刀 2024-10-15 14:42:55

我不确定在同一进程边界内拥有多个 Saga 是否效果很好 - 至少,我也遇到过问题。无论如何,将 Sagas 分成两个不同的进程可能会更好(一般来说),因为否则会导致 saga 存储上出现大量锁定和潜在的死锁。

您的消息由 2 Sagas 处理,是已发送还是已发布?如果它被发布(或可以被发布),那么将很容易将 Sagas 分成两个单独的程序集。请确保为每个 Saga 中的消息类型手动调用 Bus.Subscribe(),因为 Sagas 不会自动订阅 app.config 中列出的消息。

如果您的消息已发送,并且您无法对其进行更改,则为现有消息类型创建一个中央处理程序,该处理程序要么发布第二个消息类型以发送到两个 Sagas,要么向每个 saga 发送两条单独的消息。

I'm not sure that having more than one Saga within the same process boundary works very well - at least, I've had problems with it too. It's probably better (in general) to have Sagas separated into two different processes anyway, because otherwise it would cause a lot of locking and potentially deadlocks on your saga storage.

Is your message that is handled by 2 Sagas Sent or Published? If it's published (or can be made to), it would be easy to separate the Sagas into two separate assemblies. Just be sure to manually call Bus.Subscribe() for the message type in each Saga, since Sagas don't auto-subscribe to messages listed in the app.config.

If your message is Sent, and there's nothing you can do to change it, then create a central handler for your existing message type that either Publishes a second message type to go to both Sagas, or Sends two separate messages to each saga.

鸠书 2024-10-15 14:42:55

最后(在深入研究源代码之后)我找到了解决方案。看来唯一的方法就是实现我自己的 SagaPersister,在那里我可以做任何我想做的事情。

InMemorySagaPersister 的 NserviceBus 中的默认实现具有以下代码:

    T ISagaPersister.Get<T>(Guid sagaId)
    {
        ISagaEntity result;
        data.TryGetValue(sagaId, out result);

        return (T)result;
    }

并且在转换时发生异常。

Finally (after digging into the source code) I've found the solution. It seems the only way is to implement my own SagaPersister, where I can do anything I want.

Default implementation in NserviceBus of InMemorySagaPersister has the following code :

    T ISagaPersister.Get<T>(Guid sagaId)
    {
        ISagaEntity result;
        data.TryGetValue(sagaId, out result);

        return (T)result;
    }

And exception occurs while casting .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文