场景说明
在一个业务的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