How to create Delegates that points to static methods in runtime

One of the less known feature of .NET Reflection enable us to get reference to static methods which name is not known in compile time and to point a delegate at it.

In this example we will enumerate and call all static methods of a plugin marked with PlugInAttribute. We will use console application altrough it will work in any type of project.

1. Create MyPlugInAttribute class. We will use this attribute to mark static methods as accessible to host aplication

    [AttributeUsage (AttributeTargets.Method)]

    public class MyPlugInAttribute : Attribute

    {

    }

2. Create MyDelegate. This delegate defines signature of expected methods in PlugIn. Our delegate will require one string parameter

    /// <summary>

    /// Defines signature of expected static method

    /// </summary>

    /// <param name="x"></param>

    delegate void MyDelegate(string x);

3. Create PlugInclass.cs. It will hold PlugInClass that simulates real plug in. We will mark Method1 with our attribute

    public class PluginClass

    {

 

        [MyPlugInAttribute]

        public static void Method1(string x)

        {

            Console.WriteLine("I'm Method 1 :)");

        }

 

        public void SomeNotStaticMethod()

        {

            //It does not get executed

        }

 

        public static void Method2(string y)

        {

            //It does not get executed

            Console.WriteLine("I'm Method 2 :)");

        }

    }

4. Create host application. Host application will extract all marked methods and create delegates using CreateDelegate method of delegate object. in the next stage we will execute all delegates stored in generic Dictionary

    class Program

    {

 

        /// <summary>

        /// Show  begins here!

        /// </summary>

        /// <param name="args"></param>

        static void Main(string[] args)

        {

 

            Dictionary<string, MyDelegate> delegates =

                new Dictionary<string, MyDelegate>();

 

            Type xType = Assembly.GetExecutingAssembly().GetType("ConsoleApplication1.PluginClass");

 

            ExtractPluginFunctions(delegates, xType);

            InvokePlugInFunctions(delegates);

 

            Console.Read();

        }

 

 

        private static void InvokePlugInFunctions(Dictionary<string, MyDelegate> delegates)

        {

            foreach (string name in delegates.Keys)

                delegates[name].Invoke("any data that static method expects");

        }

 

        private static void ExtractPluginFunctions(Dictionary<string, MyDelegate> delegates, Type x)

        {

            foreach (MethodInfo mi in x.GetMethods())

            {

                if (HasMyAttributeInterface(mi))

                    AddDelegateToDictionary(delegates, mi);

            }

        }

 

        private static bool HasMyAttributeInterface(MethodInfo mi)

        {

            return mi.GetCustomAttributes(typeof(MyPlugInAttribute), true).Length > 0;

        }

 

        private static void AddDelegateToDictionary(Dictionary<string, MyDelegate> delegates, MethodInfo mi)

        {

            MyDelegate theDelegate =

                (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), mi);

 

            delegates.Add(mi.Name, theDelegate);

        }

    }

 

You can find complete source code attached at the end of the post

Published Thursday, November 01, 2007 2:03 PM by Paki
Filed under: ,

Leave a Comment

(required) 
(required) 
(optional)
(required) 
Powered by Community Server (Commercial Edition), by Telligent Systems