J'utilise la dernière version de Rebus (0.99.35) avec SimpleInjector (3.1.2). Dans mon premier exemple de projet, j'utilise SQL Server pour le transport et Sagas.Rebus Saga lance IAmInitiatedBy plusieurs fois
Le problème est que la méthode Saga Handle(StartTheSagaMessage message)
, mettant en œuvre IAmInitiatedBy<StartTheSagaMessage>
, est appelée 5 fois et je ne comprends pas pourquoi. De plus, cette méthode publie elle-même un message qui n'est jamais reçu par le bus.
Voici le code de configuration:
var container = new Container();
var assemblies = AppDomain.CurrentDomain.GetAssemblies()
.Where(i => i.FullName.StartsWith("Messages"));
container.RegisterCollection(typeof(IHandleMessages<>), assemblies);
var bus = Configure.With(new SimpleInjectorContainerAdapter(container))
.Logging(l => l.Trace())
.Transport(t => t.UseSqlServer(connectionstring, "Messages", "consumer"))
.Routing(r => r.TypeBased().MapAssemblyOf<Job>("consumer"))
.Sagas(s => s.StoreInSqlServer(connectionstring, "Sagas", "SagaIndexTable"))
.Options(o =>
{
o.SetNumberOfWorkers(1);
o.SetMaxParallelism(1);
})
.Start();
container.Verify();
bus.Subscribe<Step1FinishedMessage>().Wait();
bus.Subscribe<Step2FinishedMessage>().Wait();
var procId = Guid.NewGuid();
bus.Send(new StartTheSagaMessage() { ProcessId = procId });
Et Code Saga:
public class MySaga : Saga<MySagaData>,
IAmInitiatedBy<StartTheSagaMessage>,
IHandleMessages<Step1FinishedMessage>,
IHandleMessages<Step2FinishedMessage>
{
public IBus Bus { get; set; }
protected override void CorrelateMessages(ICorrelationConfig<MySagaData> config)
{
config.Correlate<StartTheSagaMessage>(m => m.ProcessId, s => s.SagaProcessId);
config.Correlate<Step1FinishedMessage>(m => m.ProcessId, s => s.SagaProcessId);
config.Correlate<Step2FinishedMessage>(m => m.ProcessId, s => s.SagaProcessId);
}
public async Task Handle(StartTheSagaMessage message)
{
if (IsNew == false)
return;
Trace.TraceInformation("Mysaga - got StartTheSagaMessage: {0}", message.ProcessId);
//The saga is started - Do some stuff - call webservices (in external handler)
//When this step is finished the external process replies with a "step1FinishedMessage"
this.Data.SagaProcessId = message.ProcessId;
//Fake Step1FinishMessage (should be replied from external handler)
await Bus.Send(new Step1FinishedMessage() { ProcessId = this.Data.SagaProcessId });
}
public async Task Handle(Step1FinishedMessage message)
{
Trace.TraceInformation("Mysaga - got Step1FinishedMessage: {0}", message.ProcessId);
//Sagabehaviour when the Step1 is finished by the external handler
this.Data.Step1Finished = true;
//After dalying 10 seconds - Send a step2finishedmessage
await Bus.Defer(TimeSpan.FromSeconds(10), new Step2FinishedMessage() { ProcessId = this.Data.SagaProcessId });
}
public async Task Handle(Step2FinishedMessage message)
{
await Task.Run(() =>
//return Task.FromResult<void>(() =>
{
Trace.TraceInformation("Mysaga - got Step2FinishedMessage: {0}", message.ProcessId);
//Step2 is handled - finished the saga
this.Data.Step2Finished = true;
this.MarkAsComplete();
});
}
}
L'échantillon complet est basé sur le solution available here.
Qu'est-ce que je fais mal?
Merci pour votre aide.
* solution disponible ici * utilise Autofac? – qujck
Oui, c'est le cas. La solution source utilise également d'anciens paquets nuget. – ilcorvo
Oui, je peux voir, et la mise à jour de tous les paquets produit du code qui ne compile pas. – qujck