反射详解一

本章学习内容

  1. dll-IL-metadata-反射
  2. 反射加载dll,读取module、类、方法、特性
  3. 反射创建对象,反射+简单工厂+配置文件
  4. 破坏单例 创建泛型

反射基础

反射是无处不在的,MVC-Asp.Net-ORM-IOC-AOP 几乎所有的框架都离不开反射

  1. 反编译工具不是用的反射,是一个逆向工程
  2. IL:也是一种面向对象语言,但是不太好阅读
  3. metadata元数据:数据清单,描述了DLL/exe里面的各种信息
  4. 反射Reflection:System.Reflection,是 .net Framework提供的一个帮助类库,可以读取并使用metadata

反射工具类

//加载dll
Assembly assembly1 = Assembly.Load("Ruanmou.DB.Mysql");//完整dll名称不需要后缀,从exe所在目录超找
Assembly assembly2 = Assembly.LoadFile(@"D:\xxx\xx\xx\Ruanmou.DB.Mysql.dll");//绝对路径
Assembly assembly3 = Assembly.LoadFrom("Ruanmout.DB.Mysql.dll");//当前路径   
Assembly assembly4 = Assembly.LoadFrom(@"D:\xxx\xx\xx\Ruanmou.DB.Mysql.dll");//绝对路径

反射基本使用

j简单获取全部dll中的信息
 foreach (var type in assembly1.GetTypes())
                {
                    Console.WriteLine(type.Name);
                    foreach (var method in type.GetMethods())
                    {
                        Console.WriteLine(method.Name);
                    }
                    foreach (var field in type.GetFields())
                    {
                        Console.WriteLine(field.Name);
                    }
                }
调用类型中的不同参数的构造函数
foreach (ConstructorInfo ctor in type.GetConstructors())
                {
                    Console.WriteLine(ctor.Name);
                    foreach (var paramter in ctor.GetParameters())
                    {
                        Console.WriteLine(paramter.ParameterType);
                    }
                }
                //不同的构造函数创建实例
                object oTest1 = Activator.CreateInstance(type);//无参构造函数
                object oTest2 = Activator.CreateInstance(type, new Object[] { 123 });//一个参数,参数类型类型为int的构造函数
                object oTest3 = Activator.CreateInstance(type, new Object[] { "陌商" });//一个参数,参数为字符串的构造函数
反射最简单好处示例
//统一工厂
public class SimpleFactory
    {
        private static string IDBHelperConfig = ConfigurationManager.AppSettings["IDBHelperConfig"];
        private static string DllName = IDBHelperConfig.Split(',')[1];
        private static string TypeName = IDBHelperConfig.Split(',')[0];
        public static IDBHelper CreateInstance()
        {
            Assembly assembly = Assembly.Load(DllName);
            Type type = assembly.GetType(TypeName);
            object oDBHelper = Activator.CreateInstance(type);
            IDBHelper iDBHelper = oDBHelper as IDBHelper;
            return iDBHelper;
        }
    }
  /// <summary>
    /// 数据访问类抽象
    /// </summary>
    public interface IDBHelper
    {
        void Query();
    }
Console.WriteLine("*****************Reflection+Factory+Config********************");
IDBHelper iDBHelper = SimpleFactory.CreateInstance();
iDBHelper.Query();
  1. 程序的可配置,通过修改配置文件就可以自动切换
  2. 实现类必须是事先已有的,而且在目录下面
  3. 没有写死类型,而是通过配置文件执行,反射创建的
  4. 可扩展:完全不修改原有代码,只是增加新的实现,copy,修改配置文件,就可以支持新功能
  5. 反射的动态加载和动态创建对象 以及配置文件结合

反射破坏单例模式

单例模式:类,能保证在整个进程中只有一个实例

public sealed class Singleton
    {
        private static Singleton _Singleton = null;
        private Singleton()
        {
            Console.WriteLine("Singleton被构造");
        }

        static Singleton()
        {
            _Singleton = new Singleton();
        }

        public static Singleton GetInstance()
        {
            return _Singleton;
        }
    }
}
Singleton singleton1 = Singleton.GetInstance(); //new Singleton();
Singleton singleton2 = Singleton.GetInstance();
Singleton singleton3 = Singleton.GetInstance();
Singleton singleton4 = Singleton.GetInstance();
Singleton singleton5 = Singleton.GetInstance();
Console.WriteLine($"{object.ReferenceEquals(singleton1, singleton5)}");

单例模式,都是同一个静态变量_Singleton,以上所有sigleton实例都是同一个。

Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.Singleton");
Singleton singletonA = (Singleton)Activator.CreateInstance(type, true);
Singleton singletonB = (Singleton)Activator.CreateInstance(type, true);
Singleton singletonC = (Singleton)Activator.CreateInstance(type, true);
Singleton singletonD = (Singleton)Activator.CreateInstance(type, true);
Console.WriteLine($"{object.ReferenceEquals(singletonA, singletonD)}");

反射破坏了单例—就是通过反射调用了私有构造函数,每个实例都是新的实例。

反射泛型类

 public class GenericClass<T, W, X>
    {
        public void Show(T t, W w, X x)
        {
            Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
        }
    }
Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericClass`3");//三个泛型参数
//初始化方法一
GenericClass<string, int, DateTime> genericClass = new GenericClass<string, int, DateTime>();
object oGeneric = Activator.CreateInstance(type);
//初始化方法二
Type typeMake = type.MakeGenericType(new Type[] { typeof(string), typeof(int), typeof(DateTime) });
object oGeneric = Activator.CreateInstance(typeMake);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值