转载

程序集加载与反射(二):实例篇

目录:

  • 上篇: 程序集加载与反射(一):基础篇
  • Demo: 下载

一、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);

正文到此结束
Loading...