目录:
一、Demo
下面这个Demo,使用了策略模式模仿了一下插件机制。我们举个一邮件发送的例子:
1、一个策略类库:Strategy,里面定义了邮件需要实现的接口:IEmailStrategy.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Strategy { public interface IEmailStrategy { string From { get; } string To { get; } string Subject { get; } bool Send(string from, string to, string subject); } }
2、一个具体实现类库:Target,具体的邮箱发送策略实现:Tow_Email.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Strategy; namespace Target_1 { public class Email : IEmailStrategy { public string TestField_1 = string.Empty; public int TestField_2 = 0; public Email(string from, string to, string subject) { _from = from; _to = to; _subject = subject; } private readonly string _from; private readonly string _to; private readonly string _subject; public string From { get { return _from; } } public string To { get { return _to; } } public string Subject { get { return _subject; } } public bool Send(string from, string to, string subject) { Console.WriteLine("Send Email Successed ! "); return true; } } }
3、最后我的宿主程序,ReflectionTest, 将具体的邮箱策略实现 Target_1.dll (可以看作第三方代码)dll拷贝到,宿主程序相关目录下。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ReflectionTest { class Program { static void Main(string[] args) { //获取当前主程序所在路径 string hostFilePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location); //获取dll路径 string[] dlls = System.IO.Directory.GetFiles(hostFilePath, "*.dll"); foreach (string dll in dlls) { //加载dll System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(dll); if (assembly != null && assembly.GetName().Name == "Target_1") { Console.WriteLine("Assembly name:{0}", assembly.FullName); //获取程序集中所有公共类 Type[] types = assembly.GetExportedTypes(); foreach (Type t in types) { Console.WriteLine("Type name :{0}", t.FullName); if (t.IsClass && typeof(Strategy.IEmailStrategy).IsAssignableFrom(t)) { //获取当前类中公共成员 System.Reflection.MemberInfo[] members = t.GetMembers(); string from = "K-Json@139.com"; string to = "Wold@139.com"; string subject = "Come on baby"; Console.WriteLine("----实例化----"); Strategy.IEmailStrategy email = (Strategy.IEmailStrategy)System.Activator.CreateInstance(t, from, to, subject); if (email != null) { string _f=email.From; string _t=email.To; string _s=email.Subject; email.Send(_f,_t,_s); } //字段 Console.WriteLine("----字段----"); System.Reflection.FieldInfo[] fields = t.GetFields(); foreach (var f in fields) { Console.WriteLine("Field name : {0}", f.Name); Console.WriteLine("Field type : {0}", f.FieldType.ToString()); Console.WriteLine("Field value : {0}", f.GetValue(email).ToString()); } //属性 Console.WriteLine("----属性----"); System.Reflection.PropertyInfo[] ppinfo = t.GetProperties(); foreach (var p in ppinfo) { Console.WriteLine("PropertyInfo name: {0}", p.Name); Console.WriteLine("PropertyInfo can read: {0}", p.CanRead.ToString()); Console.WriteLine("PropertyInfo can write: {0}", p.CanWrite.ToString()); Console.WriteLine("PropertyInfo value: {0}", p.GetValue(email)); } //方法 Console.WriteLine("----方法----"); System.Reflection.MethodInfo[] methodsinfo = t.GetMethods(); foreach (var mt in methodsinfo) { Console.WriteLine("MemberInfo name: {0}", mt.Name); object[] objs=new object[]{"K-Json@139.com", "Wold@139.com","Come on baby!"}; if(mt.Name=="Send") mt.Invoke(email,objs); //全能方法:此处正是执行了一下方法 t.InvokeMember("Send",System.Reflection.BindingFlags.InvokeMethod, null, email, objs); } Console.ReadKey(); } } } } } } }
总结:
1、常规反射
加载程序集 ---> 筛选类 GetExportedTypes() ---> 实例化(System.Activator.CreateInstance) ---> 获取类公共成员 GetMembers() ---> Type类的:GetFields(),GetProperties(),GetMethods()
2、全能反射:InvokeMember("Send",System.Reflection.BindingFlags.InvokeMethod, null, email, objs);