私はコネクタと呼ぶnserviceバスプロジェクトを持っています。私のコネクタは、ClientChangeMessage、ClientContactChangeMessage など、さまざまな種類のメッセージを受け取ります。私のコネクタはサガを実装していないので、各メッセージのハンドラがあるので、ClientChangeMessage には、コネクタが ClientChangeMessage を受信したときに起動される ClientChangeMessageHandler と、ClientContactChangeMessage を受信したときに ClientContactChangeMessageHandler があります。
サガの実装を見ていると、次のコードを書いていることに気付きました (クライアントの連絡先メッセージが 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; }
}
例からわかるように、CLientChangeMessage のハンドルも実装する必要があります。ClientChangeMessage のハンドラーは既に定義されています。さらに時間内に ClientChangeMessage が来る場合は、ここでもう一度ハンドラーを処理する必要がありますか?私はそれがこれではなく ClientChangeMessageHandler nad によってキャッチされ、処理されることを期待しています。
データベースにクライアントのローカル参照が見つからない場合にのみ、メッセージを保存したいと思います。ウェブ上のサガの例を見ると、これが処理される特定の場所や条件は見当たりません。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;}
}