1. 程式人生 > >.NET Framework反射總結

.NET Framework反射總結

eof 特定 service items 讀取 類型 tin res method

概述

  程序集的反射以及動態的創建類對象,是自動化編程常用的到知識原理,比如插件編程、模板設計模式,都可以采用發射機制動態的去創建實例化對象,實現類的動態加載。這裏簡單總結下,常用到的Framework反射知識點(泛型和非泛型);.NET框架的三個內置類來使用反射:System.Reflection.Assembly、System.Type和System.Activator;

  • System.Reflection.Assembly類描述了.NET的程序集.在.NET中,程序集是配置單元.對於一個典型的Windows程序,程序集被配置為單一的Win32可執行文件,並且帶有特定的附加信息,使之適應.NET運行環境.程序集也可以配置為Win32的DLL(動態鏈接庫),同樣需要帶有.NET需要的附加信息。
    System.Reflection.Assembly類可以在運行的時候取得程序集的信息.這些信息包括程序集包含的類型信息。
  • System.Type類描述了類型定義.一個類型聲明可以是一個類,接口,數組,結構體,或者枚舉.在加載了一個類之後,System.Type類可以被用於枚舉該類支持的方法,屬性,事件和接口。
  • System.Activator類用於創建一個類的實例。

程序集Assembly

  程序集的加載和讀取方式

Assembly[] AssbyCustmList = System.AppDomain.CurrentDomain.GetAssemblies();//獲取當前那所有程序集
Assembly ResltAss = typeof(IServicePlugin).Assembly;//當前類型所在程序集 Assembly tmp = Assembly.LoadFile(filepath);//文件路徑加載

程序集Type類型

  獲取程序集Type類型

Assembly tmp = Assembly.LoadFile(file);//文件路徑加載
Type[] types = tmp.GetTypes();//獲取程序集的所有類型
Type[]  Items= tmp.GetExportedTypes();//獲取程序集公用類型

判斷程序集的屬性信息:接口實現、泛型類型

    Type t=GetType();
    Type[] interfaces = t.GetInterfaces();//獲取該類型上層實現所有接口
    foreach( Type theInterface in interfaces )
    {
       if (theInterface.FullName == "WinDemo.Core.Iplugin")
       {
             ret = true;
             break;
        }
    }
    //t.GetTypes().Where(x => x.GetInterfaces().Count(p => p.FullName == "PluginUnitTestProject.IServicePlugin") >0)//(簡寫,功能同上)
    Type[] interfaces = t.GetInterface("Iplugin");//獲取該類型上層實現接口Iplugin類型 

  判斷泛型方式:IsGenericType、GetGenericTypeDefinition()和GetGenericArguments()

    private IEnumerable<Type> GetHandlerTypes<T>() where T : Command
        {
            var handlers = typeof(ICommandHandler<>).Assembly.GetExportedTypes()
                .Where(x => x.GetInterfaces()
                    .Any(a => a.IsGenericType && a.GetGenericTypeDefinition() == typeof(ICommandHandler<>) ))
                    .Where(h=>h.GetInterfaces()
                        .Any(ii=>ii.GetGenericArguments()
                            .Any(aa=>aa==typeof(T)))).ToList();

           
            return handlers;
        }

程序的創建

通過程序集的CreateInstance

            Assembly tmp = Assembly.LoadFile(filepth);//文件路徑加載
            Type[] types = tmp.GetTypes();
            bool ok = false;
            foreach (Type t in types)
            { 
                if (IsValidPlugin(t))
                {
                    IServicePlugin plugin = (IServicePlugin)tmp.CreateInstance(t.FullName);
            //動態加載程序集裏面方法,動態調用
            
MethodInfo medo = t.GetMethod("InvokeTask");medo.Invoke(serple, null);
                }
            }

通過Activator.CreateInstance

       ServicePluginAttribute srevic = null;
            foreach (Type itm in TypeItemList)
            {
                srevic = new ServicePluginAttribute();
                var serple = Activator.CreateInstance(itm);
         //動態調用程序集裏面的方法
         MethodInfo medo = t.GetMethod("InvokeTask");medo.Invoke(serple, null);
        }

.NET Framework反射總結