利用反射动态调用有自定义属性标签的类中的方法

场景说明

在一个业务的DLL中有多个类,类都有一个自定义属性(Attribute)标签。

类中的每个方法也有一个自定义属性(Attribute)标签。

在客户端知道类和方法自定义属性的值,需要动态来调用这个方法。

自定义属性

 1 namespace Test
 2 {
 3     public class TestClassAttribute : Attribute
 4     {
 5         public int ClassId { get; }
 6 
 7         public TestClassAttribute(int id)
 8         {
 9             ClassId = id;
10         }
11     }
12 }
 1 namespace Test
 2 {
 3     public class TestMethodAttribute : Attribute
 4     {
 5         public int MethodId { get; }
 6         public TestMethodAttribute(int Id)
 7         {
 8             MethodId = Id;
 9         }
10     }
11 }
 1 namespace Test
 2 {
 3     [TestClass(1)]
 4     public class TestPrint 
 5     {
 6         [TestMethod(2)]
 7         public void Print(string msg)
 8         {
 9             Console.WriteLine(msg);
10             Console.ReadKey();
11         }
12     }
13 }

动态调用

static void Main(string[] args)
        {

            Assembly assembly = Assembly.Load("Test");

            var tClass = assembly.GetTypes().FirstOrDefault(m =>
            {
                var attrArr =
                    m.GetCustomAttributes(typeof(TestClassAttribute), false).FirstOrDefault() 
                    as TestClassAttribute;
                return attrArr != null && attrArr.ClassId == 1;
            });

            if (tClass != null)
            {
                MethodInfo[] methods = tClass.GetMethods();

                var method = methods.FirstOrDefault(m =>
                {
                    var testClassAttribute =
                        m.GetCustomAttributes(typeof(TestMethodAttribute), false).FirstOrDefault() 
                        as TestMethodAttribute;
                    return testClassAttribute != null && testClassAttribute.MethodId == 2;
                });


                if (method != null)
                {
                    object[] param = new object[] { "Call  Success !" };

                    // 1. 如果Test类Print方法是静态的
                    method.Invoke(null, param);

                    // 2. 如果不是静态的,Test只有无参的构造函数
                    ConstructorInfo magicConstructor = tClass.GetConstructor(Type.EmptyTypes);
                    method.Invoke(magicConstructor.Invoke(new object[] { }), param);

                    // 3.如果Test有有参的构造函数
                    method.Invoke(Activator.CreateInstance(tClass, new object[]
                    {
                        // 构造函数的参数 
                    }), param);
                }
            }
        }

 总结

1. 学习用反射动态获取类和方法自定义标签属性。

2. 学习用反射动态调用静态方法,有/无参构造函数类的方法。

3. 实际项目中建议使用依赖注入来动态调用类。

本文博客园地址:www.cnblogs.com/struggle999/p/7009472.html 

原文地址:https://www.cnblogs.com/struggle999/p/7009472.html