前序准备,创建几个类库, IDbHelper MysqlHelper SqlHelper 一接口,两实现 ,实现query() 行为,输出
1 没有反射之前,写死的方法调用。
注意细节,不光using 对应的命名空间,还在要依赖项中,引入类库。
using Xu;
IDbHelper dbHelper1 = new MysqlHelper();
dbHelper1.query();
IDbHelper dbHelper2 = new SqlserverHelper();
dbHelper2.query();
运行效果
2 反射的what ,how why ?
2.1 什么是反射(what)
官方定义: 反射指程序可以访问、检测和修改它本身状态或行为的一种能力。 (获取读取并使用metadata )
2.2 如何使用。
2.2.1 一个基础实现的例子。
using System.Reflection;
Console.WriteLine("*********relection*********************************");
Assembly assembly1 = Assembly.Load("Xu.MysqlHelper"); //加载dll
Type type = assembly1.GetType("Xu.MysqlHelper"); //获取类型信息
Console.WriteLine("type:"+type.ToString());
object oHelper = Activator.CreateInstance(type); //创对象
IDbHelper dbHelper3 = (IDbHelper)oHelper; //类型转换
dbHelper3.query(); //调用。
加载dll > 获取类型信息 > 创对象 > 类型转换 > 调用
意义 唯一的差别,就是用字符串,创建对象并调用了。 (写死与写活的差别)
2.2.2 将上述代码进行封装,调用更简单。 (实现可配置,可扩展)
/// 创建对象
/// </summary>
public class Factory
{
public static IDbHelper createHelper()
{
Console.WriteLine("*********relection*********************************");
Assembly assembly1 = Assembly.Load("Xu.MysqlHelper"); //加载dll
Type type = assembly1.GetType("Xu.MysqlHelper"); //获取类型信息
Console.WriteLine("type:"+type.ToString());
object oHelper = Activator.CreateInstance(type); //创对象
return (IDbHelper)oHelper; //类型转换
}
}
IDbHelper dbHelper3 = Factory.createHelper();
这样,只要想办法,去变更那个创建字符串,就实现了,成生oHelper. 常用法方,读配置数据。 进一步的,加载一个新的类库,dll 文件,调整配置,就可以直接用了。
2.2.3 一些特性和用法。
1 破坏单例。
每次createInstance 时,都会调用私有方法构造方法
Singletoe s1 = Activator.CreateInstance(type, true)
2 构造函数存在多个时,
object oHelper = Activotor.CreateInstance(type, new Object[] {123})
3 带泛型时。
Assembly assembly3 = Assembly.Load("Xu.MysqlHelper"); //加载dll
Type type = assembly1.GetType("Xu.GenericClas`3"); //搞类型时,要写占位
//确定类型
Type newType = type.MakeGenericType(new Type[] {typeof(it), typeof(string), typeof("Datetime")});
object oHelper4 = Activator.CreateInstance(newType); //创对象
2.2.4 反射方法 。
Assembly as1 = Assembly.Load("Xu.MysqlHelper");
Type type = as1.GetType("Xu.ReflectTest");
object oTest = Activator.CreateInstance(type);
//无参数
MethodInfo m0 = type.GetMethod("show");
m0.Invoke(oTest, null);
MethodInfo m1 = type.GetMethod("show1");
m1.Invoke(oTest, new object[] { 123});
//静态方法调整
MethodInfo m3 = type.GetMethod("show3");
m3.Invoke(null, new object[] { "static invode" });
拿methodInfo 对象,用Invoke 方法,注意一些语法细节。
函数重载处理
类代码
public void show4()
{
Console.WriteLine("ReflectTest show4 无参数");
}
public void show4(int i)
{
Console.WriteLine("ReflectTest show4 带int" + i.ToString());
}
//调用 方法 。
MethodInfo m4 = type.GetMethod("show4", new Type[]{});
m4.Invoke(oTest, null);
MethodInfo m5 = type.GetMethod("show4", new Type[] { typeof(int)});
m5.Invoke(oTest, new object[] { 123});