Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider supporting Polymorphic Saga Mapping #3964

Open
ppittle opened this issue Jul 25, 2016 · 6 comments
Open

Consider supporting Polymorphic Saga Mapping #3964

ppittle opened this issue Jul 25, 2016 · 6 comments
Milestone

Comments

@ppittle
Copy link

ppittle commented Jul 25, 2016

I have a scenario like:

public interface ICustomSagaMessage : IMessage
{
    Guid CorrelationId {get;set;}
}

public class ExampleMessage1 : ICustomSagaMessage{}
public class ExampleMessage2 : ICustomSagaMessage{}
public class ExampleMessage3 : ICustomSagaMessage{}

public class AwesomeSaga : Saga<CustomSagaData>, 
                                              IAmStartedBy<ExampleMessag1>
                                              IHandleMessage<ExampleMessage2>, 
                                              IHandleMessage<ExampleMessage3> {}

I would have expected to be able to only need a single binding :

override void ConfigureHowToFindSaga(SagaPropertyMapper<CustomSagaData> mapper)
{
            mapper.ConfigureMapping<ICustomSagaMessage>(message => message.CorrelationId )
                .ToSaga(saga => saga.CorrelationId);
 }

However, I get an exception:
Saga AwesomeSaga contains a mapping for ICustomSagaMessage in the ConfigureHowToFindSaga method, but does not handle that message. If AwesomeSaga is supposed to handle this message, it should implement IAmStartedByMessages<ICustomSagaMessage> or IHandleMessages<ICustomSagaMessage>.

It would be nice if the mapper was able to figure out I am adding a mapping as a base class. Or will this introduce too much complexity for your team to implement the mapper?

@danielmarbach
Copy link
Contributor

@ppittle We always required having an exact mapping because when we looked at inheritance based mapping, we couldn't come up with a good way to deal with inheritance on mappings without suddenly making sagas start by magic and therefore potentially breaking backwards compatibility. But to be honest I think we haven't dug deep enough (at least not to my limited context). Thanks for the input

@ppittle
Copy link
Author

ppittle commented Jul 25, 2016

making sagas start by magic

Assembly scanning is magic :)

Ya, figured this has the potential to make mapping resolution a bit more complicated. As for "breaking backwards compatibility", if you're currently requiring exact mappings and then relax that requirement, as long as the new algorithm favors the exact matching over any mapping for a base class/interface, behavior shouldn't change?? But I'll read that as polymorphic message mapping won't be considered until NSB 7 :)

@kind-serge
Copy link

It would be nice to have message headers in the mapper, so you can do mapping based on headers rather than concrete message type.

@timbussmann
Copy link
Contributor

@TYROTOXIN Could you give us some example on what kind of headers you want to use for which decisions (and how this relates to the polymorphic messages)?

@kind-serge
Copy link

kind-serge commented Jul 29, 2016

Essentially we are building a framework which facilitates creating Sagas and communication to other services (using NSB), where a Saga gets its own unique ID assigned to it (e.g. Guid.NewGuid()). Now the end-user of such framework have to explicitly pass that ID in the message payload for every message type and create that mapping, but we'd like to hide those details from end-user and just pass around that ID in headers implicitly using outgoing/incoming behaviors. I.e. with a polymorphic mapper and access to message header we can just do smth like this:

override void ConfigureHowToFindSaga(SagaPropertyMapper<TSagaData> mapper) // where TSagaData: IFrameworkSagaData
{
    mapper.ConfigureMapping<IMessage>
        (messageContext => messageContext.Headers["SagaID"] )
         .ToSaga(saga => saga.ID);
}

@danielmarbach
Copy link
Contributor

I think with the v6 design it should be doable since we float a context bag
from the pipeline into the saga finders. In theory you could extract in
headers from there. Need to verify though.

On Friday, July 29, 2016, Serge Semenov [email protected] wrote:

Essentially we are building a framework which facilitates creating Sagas
and communication to other services (using NSB), where a Saga gets its own
unique ID assigned to it (e.g. Guid.NewGuid()). Now the end-user of such
framework have to explicitly pass that ID in the message payload for every
message type and create that mapping, but we'd like to hide those details
from end-user and just pass around that ID in headers implicitly using
outgoing/incoming behaviors.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#3964 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAKosiwsqN7oZN21bd6vVnEsOIw9lWwiks5qaj45gaJpZM4JT3ss
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants