Maintain a reference to an interface method and apply it to the implementation of that interface

I have several state classes, each of which implements an interface IState

that defines the types of methods that can be called on each:

public interface IState
{
    Type BanknoteInserted(Banknote banknoteInfo);
    Type SwitchToggled(bool switchEnabled);
    Type CardDataReceived(string track1Data, string track2Data, string track3Data);
}

      

I have a property CurrentState

that changes according to the current load IState

.

Separately (via hardware or custom interactions) I have events that these methods need to execute on CurrentState

. For simplicity of firmware and other reasons, these events are queued and processed sequentially in a background thread.

How can I refer to a specific interface method on my queue so that I can "apply" the method to which class is currently set as CurrentState

when that queue item is unloaded?

Each method call in the queue must be able to receive meaningful, typed method parameters (set during object placement).

The only possibility I was able to work with is to go back to thinking and insert tuples (string methodName, object[] methodParameters)

into my queue, but is this the best option? It seems to me that I can use delegates for this.

+3


source to share


1 answer


You can create a class that contains callbacks for each method IState

:

public class Callbacks
{
    public static readonly Func<IState, Banknote, Type> OnBanknoteInserted = 
      (s, b) => s.BanknoteInserted(b);
    // and so on, for each method

    public Func<IState, Banknote, Type> BanknoteInserted { get; set; }
    // and so on, for each method
}

      

Then in enqueue:

// put method that should be invoked on dequeue
queue.Enqueue(new Callbacks { BanknoteInserted = Callbacks.OnBanknoteInserted});

      

And then in dequeue you can do the following:

Callbacks callback = queue.Dequeue();
if (callback.BanknoteInserted != null)
    return callback.BanknoteInserted(CurrentState, banknote);
// else if (callback.SwitchToggled != null)
// and so on...

      

EDIT: To store the arguments in Enqueue

, consider this approach:
Define an interface



public interface IStateMethod
{
    Type FireEvent(IState currentState);
}

      

Create implementations for each method IState

as follows:

public class BanknoteInsertedMethod : IStateMethod
{
    private readonly Banknote banknote;

    // save all parameters here
    public BanknoteInsertedMethod(Banknote banknote)
    {
        this.banknote = banknote;
    }

    public Type FireEvent(IState currentState)
    {
        return currentState.BanknoteInserted(this.banknote);
    }
}

      

Now you can do Eqnueue

var queue = new Queue<IStateMethod>();
queue.Enqueue(new BanknoteInsertedMethod(banknote));

      

Then, on Dequeue

just call FireEvent

:

IStateMethod stateMethod = queue.Dequeue();
return stateMethod.FireEvent(currentState);

      

+2


source







All Articles