C# Action/Func Delegates in Serverless Compute

Summary

To reduce that cyclomatic complexity often produced by condition statements like IF/ELSE of Switch, it’s often easier to store functions in a Dictionary and invoke them when required. There are two types of Delegates that can be used; Action & FUNC.

Action is a delegate (pointer) to a method, that takes zero, one or more input parameters, but does not return anything.

Func is a delegate (pointer) to a method, that takes zero, one or more input parameters, and returns a value (or reference).

This is useful when building out a framework that leverages serverless compute technologies. Methods can be invoked based on needs and on different compute tiers e.g. the following examples invokes a method that in turn runs on different compute tiers:

var resource = new Dictionary<string, Action>
 {
   {"active", () => ComputeEnginePremium("Samsing Note 10")},
   {"inactive", () => ComputeEngineStandard("iPhone", 3000)}
 };

C# Implementation

Here is a basic implementation that should make things easier to understand.

namespace EAX360.MethodMapping
{
    public class Program
    {
        private static string _state;

        public static void Main()
        {
            _state = "TopicA";

            // Delegate Action; Invoke a method based on an en event change
            var actions = new Dictionary<string, Action>
            {
                {"TopicA", () => EventHandlerOne("Adam")},
                {"TopicB", () => EventHandlerTwo("iPhone", 3000)}
            };

            actions[_state]();

            // Register a new Delegate Action & Invoke a method based on an en event change
            _state = "TopicY";

            actions.Add("TopicY", () => EventHandlerFour("Syed"));

            actions[_state]();

            // Delegate Func; Invoke a method based on an en event change
            _state = "TopicC";

            var events = new Dictionary<string, Func<int>>()
            {
                {"TopicC", () => EventHandlerThree(5)},
            };

            // Invoke Func delegate functions
            int sum = events[_state]();

            Console.WriteLine(sum);
        }

        public static void EventHandlerOne(string a)
        {
            Console.WriteLine($"Hello {a}");
        }

        public static void EventHandlerTwo(string a, int b)
        {
            Console.WriteLine($"You have added {a} to the shopping cart. The total cost is £{b}");
        }

        public static int EventHandlerThree(int a)
        {
            return a + 10;
        }

        public static void EventHandlerFour(string a)
        {
            Console.WriteLine($"Hello {a}");
        }
    }
}

An implementation like this makes it easier to call a variety of methods based on state changes. This implementation also allows for new methods to be registered dynamically as follows:

actions.Add("TopicY", () => EventHandlerFour("Syed"));

Which can then be called as follows:

actions[_state]();

Leave a comment