反射是一种动态分析程序集、模块、类型、字段等目标对象的机制,它的实现依托于元数据。元数据是存储在PE 文件中的数据块,它详细记录了程序集或模块内部的结构、引用的类型和程序集和清单
一、加载dll,读取相关信息
//加载程序集
Assembly assembly = Assembly.Load("kzttest");
//获取程序集中所有的类
Type[] type = assembly.GetTypes();
//获取程序集中特定类
Type tItem = assembly.GetType("kzttest.Generics");
//获取特定类中的所有构造函数
ConstructorInfo[] cInfor = tItem.GetConstructors();
//函数实现
cInfor[0].Invoke(null);
//获取特定类中的所有属性
PropertyInfo[] cOutfor = tItem.GetProperties();
for (int i = 0; i < cOutfor.Length; i++)
{
Console.WriteLine($"name:{cOutfor[i].Name},type:{cOutfor[i].PropertyType.FullName}");
}
//获取特定类中的所有方法
MethodInfo[] methordInfo = tItem.GetMethods();
//获取特定类中的所有接口
Type[] typeInter = tItem.GetInterfaces();
二、反射创建对象
1、通过Activator.CreateInstance()方法来创建对象2、反射创建对象的代码//1.加载程序集
Assembly assembly = Assembly.Load("DB.SQLServer");
//2.获取程序集中的特定类
Type tItem = assembly.GetType("DB.SQLServer.ReflectionTest");
//3.1 无参构造函数
Activator.CreateInstance(tItem);
//3.2 一个参数的构造函数
Activator.CreateInstance(tItem ,"1");
//3.3 两个参数的构造函数
Activator.CreateInstance(tItem , 1,"2");
3、反射破坏单例,调用私有构造函数单例代码public sealed class Singleton
{
private Singleton()
{
Console.WriteLine("初始化一次");
}
private static Singleton Instance = new Singleton();
public static Singleton CreateInstance()
{
return Instance;
}
}
破坏单例,调用私有构造函数代码 //加载程序集
Assembly assembly = Assembly.Load("kzttest");
//获取程序集中特定类
Type tItem = assembly.GetType("kzttest.Singleton");
//创建对象
Activator.CreateInstance(tItem, true);
三、IOC(反射+简单工厂+配置文件)
通过XML动态创建对象注:传统创建对象、接口创建对象和直接反射创建对象 都已经发布 生成dll,无法动态修改配置文件:<appSettings>
<!--直接修改配置文件,可以修改数据库连接牛逼,可以直接切换 oracle 、mysql数据库,发布后可以直接通过改配置文件,切换数据库,代码什么也不用改,体会:反射+面向接口编程-->
<!--前提:相应的DBHelper类必须满足接口约束,需要把Oracle或MySql的dll文件拷贝到Reflection中的bin文件中 -->
<!--SQLServer改为: -->
<!--<add key="IDBHelper-dllName" value="DB.SQLServer"/>
<add key="IDBHelper-className" value="DB.SQLServer.DBHelper"/>-->
<!--Oracle改为: -->
<!--<add key="IDBHelper-dllName" value="DB.Oracle"/>
<add key="IDBHelper-className" value="DB.Oracle.DBHelper"/>-->
<!--MySql改为: -->
<add key="IDBHelper-dllName" value="DB.MySql"/>
<add key="IDBHelper-className" value="DB.MySql.DBHelper"/>
</appSettings>
简单工厂:/// <summary>
/// 简单工厂,创建对象
/// </summary>
public class SimpleFactory
{
private static string IDBHelperdllName = ConfigurationManager.AppSettings["IDBHelper-dllName"];
private static string IDBHelperClassName = ConfigurationManager.AppSettings["IDBHelper-className"];
public static IDBHelper CreateDBHelper()
{
Assembly assembly = Assembly.Load(IDBHelperdllName);
Type type = assembly.GetType(IDBHelperClassName);
object obj = Activator.CreateInstance(type);
return (IDBHelper)obj;
}
}
调用:Console.WriteLine("------------------------------------4. IOC(反射+简单工厂+配置文件)--------------------------------------");
//4. IOC(反射+简单工厂+配置文件)(不需要直接添加对其引用,只需要把相应的程序生成路径改成Reflection中即可)
IDBHelper idb3 = SimpleFactory.CreateDBHelper();
idb3.Query();
四、反射调用
//加载程序集
Assembly assembly = Assembly.Load("kzttest");
//获取程序集中特定类
Type tItem = assembly.GetType("kzttest.Generics");
//创建对象
object obj = Activator.CreateInstance(tItem);
Console.WriteLine("---------------------------------2.1 调用无参、有参的实例方法-------------------------------------");
//获取指定方法 只能一对一 不可重载 后面通过参数实现
MethodInfo methord = tItem.GetMethod("Say2");
//调用 无参
methord.Invoke(obj, null);
//获取指定方法 只能一对一 不可多态
MethodInfo methord3 = tItem.GetMethod("Say3");
//调用 有参
methord3.Invoke(obj, new object[] { "有参啊" });
Console.WriteLine("---------------------------------2.3 调用重载方法(需要在创建方法的时候,把类型传进去)-------------------------------------");
//调用重载方法 需要在创建方法的时候,把类型传进去
MethodInfo methord4 = tItem.GetMethod("Do", new Type[] { });
methord4.Invoke(obj, null);
MethodInfo methord5 = tItem.GetMethod("Do", new Type[] { typeof(string) });
methord5.Invoke(obj, new object[] { "11" });
五、好处、局限
1、反射的好处:- 反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。
- 有了反射,即可对每一个类型了如指掌。另外我还可以直接创建对象,即使这个对象的类型在编译时还不知道。
标签:反射,assembly,Assembly,C#,创建对象,tItem,Type From: https://www.cnblogs.com/buzheng11/p/17661656.html