PushCode
PushCode

Reputation: 1439

How to cast generic action delegate to concrete action delegate?

I am implementing a subscription-based reading of messages from IBM MQ websphere and I am using IBM.XMS.dll which has an event-based mechanization. Following is my code for subscription:

T is the type of data accepted by the callback function onMessageReceived. I will have to parse the message body from IMessage, convert to type T and invoke onMessageReceived fromOnMQMessageCallback

    public override void Subscribe<T>(Action<T> onMessageReceived)
    {
        try
        {
            MessageListener messageListener = new MessageListener(OnMQMessageCallback);
            _consumer.MessageListener = messageListener;

            _connection.Start();
        }
        catch (Exception ex)
        {
            throw;
        }
    }

    private void OnMQMessageCallback(IMessage msg)
    {
        try
        {
            //I want to invoke onMessageReceived in this method
        }
        catch (Exception)
        {
            throw;
        }
    }

From OnMQMessageCallback, I want to invoke onMessageReceived() which is passed into the Subscribe() method from the caller. I cannot figure out how to do it.

Upvotes: 1

Views: 673

Answers (2)

Ofir Winegarten
Ofir Winegarten

Reputation: 9355

There's no way to call the onMessageReceived if it's defined a Action<T> out side the scope of Subscribe. You simply don't know what T is.

Either you do this and let the caller handle the parsing later:

public override void Subscribe(Action<IMessage> onMessageReceived)
{
    MessageListener messageListener = new MessageListener(onMessageReceived);
    _consumer.MessageListener = messageListener;

    _connection.Start();
}

Or you parse it yourself (don't know how) and call it:

public override void Subscribe<T>(Action<T> onMessageReceived)
{
    MessageListener messageListener = new MessageListener((m) =>         
    {
        T result = (T) m.Body; // or some other casting
        onMessageReceived(result);
    });`

    _consumer.MessageListener = messageListener;

    _connection.Start();
}

No need for OnMQMessageCallback anymore.

Side Note: There's no point in try..catch..throw it's the same as not doing a try..catch at all.

Upvotes: 1

Valentin
Valentin

Reputation: 5488

You can achieve this using anonymous delegate

   MessageListener messageListener = new MessageListener((m) =>         
    try
    {
        onMessageReceived();
    }
    catch (Exception)
    {

        throw;
    });`

Upvotes: 3

Related Questions