patterncsharpMinor
Handling multiple MassTransit response types
Viewed 0 times
handlingmasstransitresponsemultipletypes
Problem
I needed to publish a message across the ESB (MassTransit) that will return a different type of object depending on how the message is processed. I wanted to implement this in a generic way so I could wire up other services with similar requirements in the same way.
Publish a request
Generic Handler to wire it up
Thoughts?
Publish a request
public IGenericResponse PublishRequest(TMessage message, Type[] potentialResponseTypes)
where TMessage : class
{
IGenericResponse commandResult = null;
_bus.PublishRequest(message, c =>
{
foreach (Type responseType in potentialResponseTypes)
{
Type genericHandler = typeof(GenericHandler).MakeGenericType(new[]{ responseType, typeof(TMessage)});
var handler = new Action(result =>
{
commandResult = (IGenericResponse) result;
});
Activator.CreateInstance(genericHandler, new object[] {c, handler});
}
c.SetTimeout(10.Seconds());
});
return commandResult;
}Generic Handler to wire it up
internal class GenericHandler
where TMessage : class
where TPayload : class
{
public GenericHandler(InlineRequestConfigurator configurator, Action handler)
{
configurator.Handle>(handler);
}
}Thoughts?
Solution
It's possible, providing
Proposed solution
c is your response from the bus, to do a lot of this without needing Reflection. Instead we can use a separate method and the joys of implicit typing to work out the type of TResponse for us.Proposed solution
public IGenericResponse PublishRequest(TMessage message, Type[] potentialResponseTypes)
where TMessage : class
{
IGenericResponse commandResult = null;
_bus.PublishRequest(message, response =>
{
foreach (Type responseType in potentialResponseTypes)
{
var genericHandler = CreateHandler(response, message);
}
c.SetTimeout(10.Seconds());
});
return commandResult;
}
private GenericHandler CreateHandler(TResponse response, TMessage message)
{
var handler = new Action(result =>
{
commandResult = (IGenericResponse) result;
});
return new GenericHandler(response, handler);
}Code Snippets
public IGenericResponse<TPayload> PublishRequest<TMessage, TPayload>(TMessage message, Type[] potentialResponseTypes)
where TMessage : class
{
IGenericResponse<TPayload> commandResult = null;
_bus.PublishRequest(message, response =>
{
foreach (Type responseType in potentialResponseTypes)
{
var genericHandler = CreateHandler(response, message);
}
c.SetTimeout(10.Seconds());
});
return commandResult;
}
private GenericHandler<TResponse, TMessage> CreateHandler<TResponse,TMessage>(TResponse response, TMessage message)
{
var handler = new Action<object>(result =>
{
commandResult = (IGenericResponse<TPayload>) result;
});
return new GenericHandler<TResponse, TMessage>(response, handler);
}Context
StackExchange Code Review Q#19071, answer score: 2
Revisions (0)
No revisions yet.