程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .net反射技術封裝

.net反射技術封裝

編輯:關於.NET

如果有人問你,如何調用一個類的private的方法或訪問一個類的私有成員,如果你不 知道反射的話,你會告訴他不可以。但是有了反射,這一切都成為可能。我有時候會想, 既然使用private來限制訪問,為什麼又要用反射去破壞這種限制呢?也許可以通過側面 來解釋這個問題,如果你要維護類的封裝性,那請不要用反射,反射會破壞類的封裝性。

但反正某些情況下,又會變得相當地有用,比如你有一個dll,其中很多類被聲明為 internal,如果你要使用這些類,而又無法修改源代碼的話,你就可以使用反射了,最近 總結了一下,對反射做了一個封裝。由於代碼比較簡單,沒有做注釋。

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace UsefulUtility
{
    public class Invoker
    {
        private static BindingFlags flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.IgnoreCase;

        public static Type GetType(Assembly asm, string typeFullName)
        {
            return asm.GetType(typeFullName);
        }

        public static Type GetInnerType(string hiddenTypeName, Type outerType)
        {
            Module typeModule = outerType.Module;
            return typeModule.GetType(hiddenTypeName);
        }

        public static MethodInfo GetMethod(Type type, string funcName, Type[] paramTypes)
        {
            if (paramTypes != null)
                return type.GetMethod(funcName, flags, null, paramTypes, null);
            else
                return type.GetMethod(funcName, flags);
        }

        public static MethodInfo GetMethod(Type type, string funcName)
        {
            return GetMethod(type, funcName, null);
        }

        public static object CallMethod(object obj, string funcName, params object[] parameters)
        {
            Type type = obj.GetType();
            MethodInfo method = GetMethod(type, funcName, GetTypesFromObjects(parameters));
            return method.Invoke(obj, parameters);
        }

        public static object CallStaticMethod(Type type, string funcName, params object[] parameters)
        {
            MethodInfo method = GetMethod(type, funcName, GetTypesFromObjects(parameters));
            return method.Invoke(null, parameters);
        }

        public static object GetProperty(object obj, string propertyName)
        {
            return GetProperty(obj, propertyName, null);
        }

        public static object GetProperty(object obj, string propertyName, params object[] index)
        {
            Type type = obj.GetType();
            return type.GetProperty(propertyName, flags).GetValue(obj, index);
        }

        public static object GetStaticProperty(Type type, string propertyName)
        {
            return GetStaticProperty(type, propertyName, null);
        }

        public static object GetStaticProperty(Type type, string propertyName, params object[] index)
        {
            return type.GetProperty(propertyName, flags).GetValue(null, index);
        }

        public static void SetProperty(object obj, string propertyName, object value)
        {
            SetProperty(obj, propertyName, value, null);
        }

        public static void SetProperty(object obj, string propertyName, object value, params object[] index)
        {
            Type type = obj.GetType();
            type.GetProperty(propertyName, flags).SetValue(obj, value, index);
        }

        public static void SetStaticProperty(Type type, string propertyName, object value)
        {
            SetStaticProperty(type, propertyName, value, null);
        }

        public static void SetStaticProperty(Type type, string propertyName, object value, params object[] index)
        {
            type.GetProperty(propertyName, flags).SetValue(null, value, index);
        }

        public static object GetField(object obj, string fieldName)
        {
            Type type = obj.GetType();
            return type.GetField(fieldName, flags).GetValue (obj);
        }

        public static object GetSaticField(Type type, string fieldName)
        {
            return type.GetField(fieldName, flags).GetValue (null);
        }

        public static void SetField(object obj, string fieldName, object value)
        {
            Type type = obj.GetType();
            type.GetField(fieldName, flags).SetValue(obj, value);
        }

        public static void SetStaticField(Type type, string fieldName, object value)
        {
            type.GetField(fieldName, flags).SetValue(null, value);
        }

        private static ConstructorInfo GetConstructor(Type type, Type[] paramTypes)
        {
            return type.GetConstructor(paramTypes);
        }

        public static object CreateInstance(Type type, Type[] paramTypes, params object[] parameters)
        {
            return GetConstructor(type, paramTypes).Invoke (parameters);
        }

        public static object CreateInstance(Type type, params object [] parameters)
        {
            return GetConstructor(type, GetTypesFromObjects (parameters)).Invoke(parameters);
        }

        private static Type[] GetTypesFromObjects(object[] objs)
        {
            Type[] types = new Type[objs.Length];
            for (int i = 0; i < types.Length; i++)
                types[i] = objs[i].GetType();
            return types;
        }

        public static void AddEventHandler(object obj, string eventName, MethodInfo method, object methodOwner)
        {
            EventInfo eventInfo = obj.GetType().GetEvent (eventName, flags);
            Delegate eventDeleg = Delegate.CreateDelegate (eventInfo.EventHandlerType, methodOwner, method);
            eventInfo.AddEventHandler(obj, eventDeleg);
        }

        public static void RemoveEventHandler(object obj, string eventName, MethodInfo method,object methodOwner)
        {
            EventInfo eventInfo = obj.GetType().GetEvent (eventName, flags);
            Delegate eventDeleg = Delegate.CreateDelegate (eventInfo.EventHandlerType, methodOwner, method);
            eventInfo.RemoveEventHandler(obj, eventDeleg);
        }
    }
}

下面的代碼對上面的一些方法進行測試,由於手頭只有一個Fetion SDK.dll的文件, 所以就拿他開刀了,實現簡單的登錄,登錄後發送一條測試信息到我的手機,為了安全略 去了某些信息。

using System;
using System.Collections.Generic;
using System.Text;
using UsefulUtility;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static object sdk;
        static Assembly asm;
        [STAThread]
        static void Main(string[] args)
        {
            // 載入程序集
            asm = Assembly.LoadFrom("Fetion SDK.dll");
            // 獲取Fetion SDK的類型
            Type type = Invoker.GetType(asm, "com.hetaoos.FetionSDK.FetionSDK");
            // 實例化sdk
            sdk = Invoker.CreateInstance(type);
            // 獲取賬號管理的屬性
            object accountManager = Invoker.GetProperty(sdk, "AccountManager");
            // 設置用戶名和密碼
            Invoker.CallMethod(accountManager, "FillUserIdAndPassword", new object[] { "手機號碼", "飛信密碼", false });
            // 監聽事件
            Invoker.AddEventHandler(sdk, "SDK_UserSatusChange", Invoker.GetMethod(typeof(Program), "sdk_SDK_UserSatusChange"), null);
            // 調用登錄方法
            Invoker.CallMethod(accountManager, "Login");
        }
        static void Hello()
        {
            Console.WriteLine("hello in Hello");
        }

        static void sdk_SDK_UserSatusChange(object sender, EventArgs e)
        {

            Console.WriteLine(Invoker.GetProperty(e, "NewStatus"));
            Console.WriteLine(Invoker.GetSaticField (Invoker.GetType(asm, "Imps.Client.UserAccountStatus"), "Logon"));
            // 這裡用==不好使,要用Equals,不知道為什麼
            if (Invoker.GetProperty(e, "NewStatus").Equals (Invoker.GetSaticField(Invoker.GetType(asm, "Imps.Client.UserAccountStatus"), "Logon")))
            {
                Console.WriteLine("hello");
                object contactControl = Invoker.GetProperty (sdk, "ContactControl");
                object sendSMS = Invoker.GetProperty (contactControl, "SendSMS");
                Invoker.CallMethod(sendSMS, "SendSMS", "要發 送信息的飛信號或手機號碼", "hello, a test");
            }
        }
    }
}

原文地址:http://www.cnblogs.com/dlutwy/archive/2009/04/28/1445352.html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved