Handling multiple MassTransit response types 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

public IGenericResponse&lt;TPayload&gt; PublishRequest&lt;TMessage, TPayload&gt;(TMessage message, Type[] potentialResponseTypes)
        where TMessage : class
{
    IGenericResponse&lt;TPayload&gt; commandResult = null;

    _bus.PublishRequest(message, c =&gt;
    {
        foreach (Type responseType in potentialResponseTypes)
        {
            Type genericHandler = typeof(GenericHandler&lt;,&gt;).MakeGenericType(new[]{ responseType, typeof(TMessage)});

            var handler = new Action&lt;object&gt;(result =&gt;
            {
                commandResult = (IGenericResponse&lt;TPayload&gt;) result;
            });

            Activator.CreateInstance(genericHandler, new object[] {c, handler});
        }

        c.SetTimeout(10.Seconds());
    });

    return commandResult;
}


Generic Handler to wire it up

internal class GenericHandler&lt;TPayload, TMessage&gt;
    where TMessage : class
    where TPayload : class
{
    public GenericHandler(InlineRequestConfigurator&lt;TMessage&gt; configurator, Action&lt;object&gt; handler)
    {
        configurator.Handle&lt;GenericResponse&lt;TPayload&gt;&gt;(handler);
    }
}


Thoughts?
It's possible, providing 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&lt;TPayload&gt; PublishRequest&lt;TMessage, TPayload&gt;(TMessage message, Type[] potentialResponseTypes)
        where TMessage : class
{
    IGenericResponse&lt;TPayload&gt; commandResult = null;

    _bus.PublishRequest(message, response =&gt;
    {
        foreach (Type responseType in potentialResponseTypes)
        {
            var genericHandler = CreateHandler(response, message);
        }

        c.SetTimeout(10.Seconds());
    });

    return commandResult;
}

private GenericHandler&lt;TResponse, TMessage&gt; CreateHandler&lt;TResponse,TMessage&gt;(TResponse response, TMessage message)
{
    var handler = new Action&lt;object&gt;(result =&gt;
    {
        commandResult = (IGenericResponse&lt;TPayload&gt;) result;
    });
    return new GenericHandler&lt;TResponse, TMessage&gt;(response, handler);
}