Re: Respond with different contract

44 views
Skip to first unread message
Message has been deleted

Alexey Zimarev

unread,
Jun 15, 2017, 2:01:39 PM6/15/17
to masstransit-discuss
Both classes and interfaces are supported. The list of message types is carried in message metadata, so it is always available

However, your consumer explicitly consumes the base interface, so the consume context get exactly that type deserialised. This is because MT does not know what type it is since there is more than one, so it deserialises to the one you can consume.

If you need to get another payload, you can always use 

var anotherMessage = context.GetPayload<AnotherMessage>();


if you know that you received AnotherMessage

On Thursday, June 15, 2017 at 4:45:14 PM UTC+2, Tim Cools wrote:
I have a request/response situation and I need to support different return contracts. I first tried anticancer of a value object in the response:

class SomeResponse
{
   
public Product { get;set; }
}

class Product { ... }
class Product1 : Product { ... }
class Product2 : Product { ... }

But this is not supported  by masstransit so I tried to return different response interfaces as that should be supported:

consumer:

public Task Consume(ConsumeContext<SomeRequest> request)
{
 context.Respond<IProduct1Response>(new IProduct1Response( ... )); 
}


interface IProductResponse { ... }
interface IProduct1Response : IProductResponse { ... }
interface IProduct2Response : IProductResponse { ... }

When I create and call a IRequestClient like this

IRequestClient<SomeRequest, IProductResponse> client = ...
var response = client.Request(new SomeResponse());

The response is always of type IProductResponse and not of the more specific interface.

So my question is: Is returning different data sets somehow support with the request/response?

Tim Cools

unread,
Jun 15, 2017, 3:10:14 PM6/15/17
to masstransit-discuss
Interesting! Any idea how to get the context of a response (on the client side)?

Thanks for the feedback!

Alexey Zimarev

unread,
Jun 15, 2017, 3:24:16 PM6/15/17
to masstransit-discuss
Looked at overloads, there is one that takes additional parameter for the request configuration. It can be used like this:

            _request = Bus.Request(InputQueueAddress, new PingMessage(), x =>
           
{
                x
.ConversationId = _conversationId;


                _response
= x.Handle<PongMessage>(async context =>
               
{
                   
Console.WriteLine("Response received");
               
}, cfg => cfg.UseExecute(context => _responseMiddleware.TrySetResult(context)));
                x
.Timeout = TestTimeout;
           
});
            await _request;

As you can see there, you can have your own handler there, which receives the context as a parameter and you get get the payload there.

Alexey Zimarev

unread,
Jun 15, 2017, 3:31:26 PM6/15/17
to masstransit-discuss
Just for clarification - you have to await the _response as well to get the actual response. Handle<T> returns Task<T>. You would probably need to hack it a bit by trying to get your "other" payload from inside the handler delegate and storing it in an outside scope of the caller method. I don't know the use case, quite sure this can be avoided, but potentially you can do this.

Tim Cools

unread,
Jun 16, 2017, 2:13:36 AM6/16/17
to masstransit-discuss
Use-case: the client wants to trigger a calculation the use of request/response. Depending on some factors decided in the service a different calculation is executed and a different set of data is returned. The client want to receive the result of the application immediately to display to the user.

It feels indeed very hack-ish and I'm very tempted to use Web-Api as this is synchronous communication. The reason I investigating whether the use-case fits in the request/response model is that all other communication is async and I hoped to avoid to introduce a new technology for this edge cases if it can be avoided.
Reply all
Reply to author
Forward
0 new messages