Search code examples
rebussaga

Auto-correlation in saga for Requst/Reply


I wanted to ask, do I understand it correctly that thanks to this https://github.com/rebus-org/Rebus/issues/105 when I do saga for Request/Reply I can leave ConfigureHowToFindSaga empty?

If it's true it would be nice to mention it in Wiki page, as well as the need for registering saga in adapter :)

The code below seems to work, could you please see if it's ok?

namespace ConsoleApplication1
{
    class Program
    {
        static IBus bus;
        static void Main(string[] args)
        {
            var adapter = new BuiltinContainerAdapter();

            adapter.Register<SampleSaga>(() => new SampleSaga(bus));

            bus = Configure.With(adapter)
                             .Logging(l => l.ColoredConsole())
                             .Transport(t => t.UseMsmq("enpoint1", "endpoint1_errors"))
                             .MessageOwnership(x => x.FromRebusConfigurationSection())
                             .Sagas(x => x.StoreInMemory())
                             .CreateBus()
                             .Start();

            bus.SendLocal(new SampleMessage() { Test = "Hi there" });
        }
    }

    class SampleSaga : Saga<MessageHolder<SampleMessage>>,
                                           IAmInitiatedBy<SampleMessage>,
                                           IHandleMessages<Response>
    {
        IBus bus;

        public SampleSaga(IBus bus)
        {
            this.bus = bus;
        }

        public override void ConfigureHowToFindSaga()
        {
        }

        public void Handle(SampleMessage message)
        {
            Data.Message = message;
            bus.Send(new Request());
        }

        public void Handle(Response message)
        {
            Console.Write(string.Format("Response arrived. Holded message: {0}", Data.Message.Test));
            MarkAsComplete();
        }
    }

    class MessageHolder<T> : ISagaData
    {
        public Guid Id { get; set; }
        public int Revision { get; set; }
        public T Message { get; set; }
    }

    class SampleMessage
    {
        public string Test { get; set; }
    }
}


namespace ConsoleApplication2
{
    class Program
    {
        static IBus bus;
        static void Main(string[] args)
        {
            var adapter = new BuiltinContainerAdapter();

            adapter.Handle<Request>(x => bus.Reply(new Response()));

            bus = Configure.With(adapter)
                             .Logging(l => l.ColoredConsole())
                             .Transport(t => t.UseMsmq("endpoint2", "endpoint2_errors"))
                             .MessageOwnership(x => x.FromRebusConfigurationSection())
                             .CreateBus()
                             .Start();
        }
    }

    public class Request
    {

    }

    public class Response
    {

    }
}

Solution

  • Yes it's true, and I agree with you that it should be documented somewhere :)

    The feature has been there for quite some time now, though, and I haven't used it that much - mostly because I feel that it's a little bit too black box to be immediately understandable, which I think code should be most of the time.

    My feelings could be caused by me having used the feature too little, though, so I might get another feeling some time in the future :)

    Your code looks fine, and I think it should work perfectly. Now, I know it's just a simple POC, but please remember to "host" your container adapter somewhere for the duration of the application lifetime, and please remember to dispose it when the application shuts down.