Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to have a Fire method that look like this Fire(TTrigger, params object[] triggerArgs)? #464

Open
dutbu6283 opened this issue Oct 24, 2021 · 1 comment

Comments

@dutbu6283
Copy link

Hi,
I want to create a general method called Fire that will either fire the method Fire(TTrigger trigger) if no argument is given or fire the method Fire(TriggerWithParameters trigger, params object[] args) if arguments are given.

But to be able to do this I need to have access to the current state TriggerParameter "list". My question is, is there a way to access this "list" in Stateless?

When I read the Stateless source code in src/Stateless/StateMachine.cs I can see that the method InternalFire(TTrigger trigger, params object[] args) has the same functionality I want, but sadly it is private. It would be nice to have a public fire method that looks like Fire(TTrigger, params object[] args) instead of using the method Fire(TriggerWithParameterstrigger, paramsobject[] args).

Btw it seems that there doesn't exist a corresponding async version of the Fire(TriggerWithParameterstrigger, paramsobject[] args). I use the Fire(TriggerWithParameterstrigger, paramsobject[] args) method in my unit tests and want to be able to use it as an async function.

public enum State { Open, Assigned, Derefered }
public enum Trigger { Assign, Defer }

public class Program
{
    private State currentState;
    private StateMachine<State, Trigger> machine;
    private Dictionary<Trigger, StateMachine<State, Trigger>.TriggerWithParameters> triggerWithParameters;

    private StateMachine<State, Trigger>.TriggerWithParameters<Trigger> assignTrigger;

    public Program()
    {
        currentState = State.Open;
        machine = new StateMachine<State, Trigger>(currentState);

        assignTrigger = machine.SetTriggerParameters<Trigger>(Trigger.Assign);

        triggerWithParameters = new Dictionary<Trigger, StateMachine<State, Trigger>.TriggerWithParameters>
        { 
            {Trigger.Assign, assignTrigger}
        };

        machine.Configure(State.Open)
            .Permit(Trigger.Defer, State.Assigned)
            .PermitDynamic(assignTrigger, ChoicePseudoState);
    }

    public void Fire(Trigger trigger, params object[] triggerArgs)
    {
        if (triggerArgs?.Length == 0)
        {
            machine.Fire(trigger);
            return;
        }
        else if (triggerWithParameters.TryGetValue(trigger, out var triggerWithParameter))
        {
            machine.Fire(triggerWithParameter, triggerArgs);
            return;
        }

        throw new NotImplementedException();
    }

    private State ChoicePseudoState(Trigger transitionTrigger)
    {
        if (Trigger.Defer == transitionTrigger)
        {
            return State.Derefered;
        }

        throw new NotImplementedException();
    }

    public static void Main()
    {
        var myMachine = new Program();

        myMachine.Fire(Trigger.Assign, Trigger.Defer);
    }
}
@ChaseFlorell
Copy link

I came here for this exact issue. I need to be able to fire a trigger with an array of objects as its parameter.

I can see that the strongly typed public methods simply call the internal method and cast the parameters to objects, can we please rename the internal method and make it public? It can obviously still maintain the same behavior as to not introduce any breaking changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants