Nservicebus 不可能有两个saga处理相同的消息类型

Nservicebus 不可能有两个saga处理相同的消息类型,nservicebus,Nservicebus,我有两个不同的传奇(我指的是传奇类型)处理相同的消息 public class AttachMessageToBugSaga : TpSaga<AttachMessageToBugSagaData>, IAmStartedByMessages<MessageIsNotAttached>, IHandleMessages<MessageAttachedToGeneralMessage> { public override voi

我有两个不同的传奇(我指的是传奇类型)处理相同的消息

     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; }
    }
公共类附件消息:TpSaga、IAmStartedByMessages、IHandleMessages
{
公共覆盖无效配置HowtoFindsaga()
{
配置映射(
saga=>saga.Id,
message=>message.SagaId
);
}
公共无效句柄(MessageIsNotAttachedToBug消息)
{
发送(新的AttachMessageGeneralCommand{MessageId=66,GeneralId=13});
}
公共无效句柄(MessageAttachedToGeneralMessage)
{
//在这里做些什么
}
}
公共类附件信息:IContainSagaData
{
公共Guid Id{get;set;}
公共字符串发起者{get;set;}
公共字符串OriginalMessageId{get;set;}
}
公共类AttachMessageToRequestSaga:TpSaga、IAmStartedByMessages、IHandleMessages
{
公共覆盖无效配置HowtoFindsaga()
{
配置映射(
saga=>saga.Id,
message=>message.SagaId
);
}
公共无效句柄(MessageIsNotAttachedMessageToRequest消息)
{
//在这里做些事情
}
公共无效句柄(MessageAttachedToGeneralMessage)
{
//在这里做些事情
}
}
公共类AttachMessageToRequestSagaData:IContainSagaData
{
公共Guid Id{get;set;}
公共字符串发起者{get;set;}
公共字符串OriginalMessageId{get;set;}
}
运行示例时,我得到一个异常:

System.InvalidCastException:无法将类型为“MyCustomPlugin.AttachMessageGeneralSagaData”的对象强制转换为类型为“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();
    }
}
公共类SagaFinder:IFindSagas.Using,
IFindSagas.使用,
IFindSagas.使用,
IFindSagas。使用
{
AttachMessageGetGeneralSAGADATA IFindSagas.Using.FindBy(MessageAttachedGeneralMessage)
{
返回ObjectFactory.GetInstance();
}
AttachMessageToRequestSagaData IFindSagas.Using.FindBy(MessageAttachedToGeneralMessage)
{
返回ObjectFactory.GetInstance();
}
public AttachmentMessageToRequestsAgadata FindBy(MessageIsNotAttachedToRequest message)
{
返回新的AttachMessageToRequestSagaData();
}
公共附件消息getorequestsagadata FindBy(消息为notattachedtobug消息)
{
返回新的AttachMessageToRequestSagaData();
}
}
但是我没有进入我的“MessageAttachedToGeneralMessage”查找程序。
请告诉我是否有其他的解决方法,或者如何使这个例子起作用。

我不确定在同一个流程边界内有多个传奇是否能很好地发挥作用-至少,我也遇到了一些问题。无论如何,最好(通常)将saga分成两个不同的进程,否则会导致saga存储上出现大量锁定和潜在死锁

你的信息是由2个传奇处理的,是发送的还是发布的?如果它出版了(或者可以制作成),那么将这些传奇故事分成两个独立的组合就很容易了。只要确保在每个Saga中手动调用Bus.Subscribe()作为消息类型,因为Saga不会自动订阅app.config中列出的消息

如果您的消息已发送,但您无法更改它,那么请为您现有的消息类型创建一个中心处理程序,该处理程序要么发布第二个消息类型以转到两个传奇,要么向每个传奇发送两条单独的消息。

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

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

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

        return (T)result;
    }
T ISagaPersister.Get(Guid sagaId)
{
Isaga实体结果;
数据。TryGetValue(sagaId,输出结果);
返回(T)结果;
}

铸造时出现异常。

谢谢你的回答,大卫。我不清楚为什么把传奇故事分成不同的过程比较好。我在一个NServiceBusHost.exe进程中运行了很多传奇故事。我需要很多这样的工具来将我的流程划分为逻辑上的小部分。所以我有一些类似于状态机的东西,每一个传奇都能帮助我切换到一个新的状态。但我理解你的想法。应该行得通