I have a nservice bus project which which i will call connector. My connector receives variouis kinds of messages for example ClientChangeMessage, ClientContactChangeMessage. My connector has not implemented saga so i have handler for each message so for ClientChangeMessage I have ClientChangeMessageHandler which gets fired when connector receives ClientChangeMessage and a ClientContactChangeMessageHandler when i receive a ClientContactChangeMessage.
Now while looking at the sagas implementation i found myself writing the following code (If the Client contact message comes before the ClientChange message i.e the client does not exist in the database):
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; }
}
As can be seen from the example I now have to implement the handle for the CLientChangeMessage as well , now i have already defined a handler for my ClientChangeMessage ,do i have to handle it again over here because if further on in time the ClientChangeMessage does come i would expect it to be caught and processed by the ClientChangeMessageHandler nad not by this one.
I would like to store a message if and only if i don't find the local reference for the Client in my database . Looking at the examples for saga on the web i dont't see any particular place or condition where this would be handled. I am hoping i would be storing the message inside the ClientContactChange handle method.
Any help would be much appreciated,
Thanks
UPDATE:
It would seem that i did not understand properly how to implement NService Bus Saga. The mistake which i made here according to me was that I considered A Client Contact change to be a single entity i.e independent of the Client Change message. So therefore i think i ma wrong in implementing the Saga just for client contact change . Here is how I had to change my code:
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;}
}