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

时间:2010-12-20 10:35:24

标签: nservicebus

我有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”的查找器。 请告诉我是否有其他解决方法,或者如何使这个例子有效。

2 个答案:

答案 0 :(得分:2)

我不确定在同一个过程边界内有多个Saga的效果非常好 - 至少,我也遇到了问题。不管怎样,将Sagas分成两个不同的进程可能会更好(一般情况下),否则会导致很多锁定并且可能会导致你的传奇存储死锁。

您的消息是由2个Sagas发送还是已发布处理的?如果它已经发布(或者可以制作),那么将Sagas分成两个独立的组件就很容易了。请确保在每个Saga中手动调用Bus.Subscribe()获取消息类型,因为Sagas不会自动订阅app.config中列出的消息。

如果您的消息是已发送的,并且您无法更改它,则为您现有的消息类型创建一个中央处理程序,或者发布第二个消息类型以转到两个Sagas,或者向每个saga发送两个单独的消息

答案 1 :(得分:0)

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

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

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

        return (T)result;
    }

施法时发生异常。