【问题标题】:Nservice bus sagas implemetationNservicebus sagas 实现
【发布时间】:2013-07-31 16:24:03
【问题描述】:

我有一个 nservice 总线项目,我将其称为连接器。我的连接器接收各种类型的消息,例如 ClientChangeMes​​sage、ClientContactChangeMes​​sage。我的连接器没有实现 saga,所以我对每条消息都有处理程序,所以对于 ClientChangeMes​​sage,我有 ClientChangeMes​​sageHandler,当连接器接收到 ClientChangeMes​​sage 时会触发它,当我收到 ClientContactChangeMes​​sage 时会触发 ClientContactChangeMes​​sageHandler。

现在在查看 sagas 实现时,我发现自己正在编写以下代码(如果客户端联系消息出现在 ClientChange 消息之前,即客户端不存在于数据库中):

public class ClientContactChangeMessageHandler : ClientMessageHandler, 
    IHandleMessages<ClientContactChangeMessage>, 
    IAmStartedByMessages<ClientContactChangeMessage>, 
    IHandleMessages<ClientChangeMessage>
{
    [SetterProperty]
    public IClientContactChangeDb ClientContactChangeDb{get;set;}

    [SetterProperty]
    public IBusRefTranslator BusRefTranslator{get;set;}

    static ClientContactChangeMessageHandler()
    {
        Logger = LogManager.GetLogger(typeof (ClientContactChangeMessageHandler));
    }

    static ILog Logger;

    public void Handle(ClientContactChangeMessage message)
    {
        //Some handling logic
    }

    public void Handle(ClientChangeMessage message)
    {
        throw new NotImplementedException();
    }

    public override void ConfigureHowToFindSaga()
    {
        ConfigureMapping<ClientContactChangeMessage>(s => s.Id, m => m.Id);
        ConfigureMapping<ClientChangeMessage>(s => s.Id, m => m.Id);
        // Notice that we have no mappings for the OrderAuthorizationResponseMessage message. This is not needed since the HR
        // endpoint will do a Bus.Reply and NServiceBus will then automatically correlate the reply back to
        // the originating saga
    }
}


public class ClientMessageHandler : BaseMessageHandler
{
}

public class BaseMessageHandler : Saga<MySagaData>
{
}

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

从示例中可以看出,我现在还必须实现 CLientChangeMes​​sage 的句柄,现在我已经为我的 ClientChangeMes​​sage 定义了一个处理程序,我是否必须在这里再次处理它,因为如果进一步及时ClientChangeMes​​sage 确实来了,我希望它被 ClientChangeMes​​sageHandler 捕获和处理,而不是被这个。

当且仅当我在我的数据库中找不到客户端的本地引用时,我想存储一条消息。查看网络上 saga 的示例,我没有看到任何特定的地方或条件可以处理。我希望我会将消息存储在 ClientContactChange 句柄方法中。

任何帮助将不胜感激,

谢谢

更新:

我似乎没有正确理解如何实现 NService Bus Saga。根据我的说法,我在这里犯的错误是我认为客户联系变更是一个单一的实体,即独立于客户变更消息。因此,我认为我只为客户联系更改而实施 Saga 是错误的。以下是我必须更改代码的方法:

 public class ClientSaga : Saga<ClientSagaState>, 
        IAmStartedByMessages<ClientChangeMessage>, 
        IAmStartedByMessages<ClientContactChangeMessage>, 
        IHandleTimeout<ClientSagaState>
    {
        [SetterProperty]
        public IClientContactChangeDb ClientContactChangeDb{get;set;}

        [SetterProperty]
        public IBusRefTranslator BusRefTranslator{get;set;}



        public void Handle(ClientContactChangeMessage message)
        {
            //Some handling logic
            //Check if client is not in database then store the state
            this.ClientContactChange=message;
            //if client is in the data base then 
            MarkAsComplete();
        }

        public void Handle(ClientChangeMessage message)
        {
            //Update or create the client depending on the situation
            //check for dependencies
            if(this.ClientContactChange !=null)
            {
                 //Handle the contact change
            }
        }

        public override void ConfigureHowToFindSaga()
        {
            ConfigureMapping<ClientContactChangeMessage>(s => s.ClientRef, m => m.ClientRef);
            ConfigureMapping<ClientChangeMessage>(s => s.ClienttnRef, m => m.Id);
            // Notice that we have no mappings for the OrderAuthorizationResponseMessage message. This is not needed since the HR
            // endpoint will do a Bus.Reply and NServiceBus will then automatically correlate the reply back to
            // the originating saga
        }
    }


    public class ClientSagaState: IContainSagaData
    {
        //i dont need these three fields
        public Guid Id { get; set; }
        public string Originator { get; set; }
        public string OriginalMessageId { get; set; }

       // the fields which i needed
       public Guid ClientRef {gee; set;}
       public ClientChangeMessage ClientChange {get;set;}
       public ClientContactChange ClientContactChange {get;set;}

    }

【问题讨论】:

  • 我很确定您仍然需要映射 OrderAuthorizationResponseMessage。 saga 仍然需要找到该消息的特定实例。顺便说一句,您可能可以取消您传奇的所有继承。归根结底,您仍在实现 Saga,它已经需要一个用于 IContainSaga 数据的类。

标签: c# nservicebus saga


【解决方案1】:

由于两个处理程序都处理相同的消息类型,因此都将被调用。如果您愿意,可以使用 ISpecifyMessageHandlerOrdering 指定调用它们的顺序。此外,您可以根据可能解决次要问题的条件短路此链。

如果这不起作用,您可能需要考虑对消息进行版本控制,以优雅的方式支持这两种情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多