Search code examples
c#stateless-state-machine

Get permitted triggers with guard conditions in Stateless (.NET state machine library)


Background:

I have same Trigger with mutually exclusive guard conditions defined with PermitIf that will cause transition to different states depending on those conditions.

Guards have Descriptions defined and they show up nicely in brackets in exported DOT graph, so it is easy to follow through.

machine
   .Configure(Status.Registered)
   .PermitIf(Activity.Submit, Status.Submitted, IsGoodRating, "Is good  rating")
   .PermitIf(Activity.Submit, Status.Denied, IsBadRating, "Is bad rating")

Now, I know there is machine.PermittedTriggers property that returns allowed Triggers in current state which is great, but here is the question.

Question :

Is there a way to get a list of PermittedTriggers with corresponding guard conditions for status Registered in this case?


Solution

  • I guess you could do something like this, but... I don't know how helpful it is:

     class Program
    {
        enum Status { Registered, Submitted, Denied }
    
        static void Main(string[] args)
        {
            int currentRating = 91;
            RatingTrigger RatingTrigger = new RatingTrigger();
    
            StateMachine<Status, Trigger> _sm = new StateMachine<Status, Trigger>(Status.Registered);
            _sm.Configure(Status.Registered)
                .PermitIf(RatingTrigger, Status.Submitted, () => RatingTrigger.Guard(currentRating), RatingTrigger.GuardDescription)
                .PermitIf(RatingTrigger, Status.Denied, () => RatingTrigger.Guard(currentRating), RatingTrigger.GuardDescription);
    
            var list = _sm.PermittedTriggers;
    
            foreach (var item in list)
            {
                if (item.GetType().Equals(typeof(RatingTrigger)))
                {
                    Console.WriteLine(((RatingTrigger)item).GuardDescription);
                }
                else
                Console.WriteLine(item);
            }
    
        }
        private static bool evaluate()
        {
            return true;
        }
    }
    public abstract class Trigger
    {
        public abstract bool Guard(object something);
    }
    public class RatingTrigger : Trigger
    {
        public string GuardDescription = "This Guard evaluaties the current rating. Retuns true if good rating, false if bad rating";
        public override bool Guard(object rating)
        {
             return  (((int)rating) > 90);
        }
    }