asp.net 反射reflection(原理读元数据,3种加载方法,反射的几种调用方法,反射在MVC,ORM中的应用)
反射高级应用
反射reflection:3种动态加载.dll的方法
反射定义:
c#代码--》VS 编译器编译dll,exe(metadata元数据,IL,)-->CLR,JIT 运行时环境将dll,exe 编译为电脑cpu可以识别的机器码01010001
reflection 是一个帮助类,可以读取元数据,可以使用元数据里的元素;
反射使用:
常规用法:
1.引入程序集;
2.创建对象;
3.调用方法:
idbhelper idb=new sqlserverhelper();
反射用法:
1.动态加载dll
Assembly assem=Assembly.Load("AspNetCore.DB.SqlServer");//动态加载dll,默认在当前程序所在目录下查找;
Assembly assem=Assembly.LoadFile(@"D:\XXX\XXPAHT\bin\debut\netcoreapp3.1\AspNetCore.DB.SqlServer.dll");//动态加载dll;要求全路径
Assembly assem=Assembly.LoadFrom("AspNetCore.DB.SqlServer.dll");//动态加载dll;默认在当前程序所在目录下查找
foreach(var type in assemble.GetTypes())
{
Console.WriteLine($"{type.GetFullName}");
}
2.获取类型:
Type type=assem.GetType("AspNetCore.DB.SqlServer.SqlServerHelper");
3.创建对象:
//object osqlhelper=Activator.CreateInstance(type);// object 声明时确定类型;
dynamic dsqlhelper=Activator.CreateInstance(type);// object 调用时确定类型;
dsqlhelper.Query();
4.类型转换:
//IDbHelper dbphelper=(IDbHelper)osqlhelper;
IDbHelper dbphelper=osqlhelper as IDbHelper;
反射的好处:
1.断开对细节的依赖;
2.反射+配置文件==程序的可配置,可扩展
添加配置文件
3.配置文件json要设置为始终复制属性;
4.copy dll 文件;
反射黑科技:
1.反射可以突破访问修饰符的权限;
2.可以调用到普通方式调用不到的东西;
Assembly assem=Assembly.Load("AspNetCore.DB.SqlServer");
Type type=assem.GetType("AspNetCore.DB.SqlServer.SqlServerHelper");
Sqlhelper sqlhelp1=(Sqlhelper)Activator.CreateInstance(type,true); //生成的3个sqlhelp1不同对象
Sqlhelper sqlhelp2=(Sqlhelper)Activator.CreateInstance(type,true);
Sqlhelper sqlhelp3=(Sqlhelper)Activator.CreateInstance(type,true);
public class simpleFactory{
public static IDbHelper CreateInstance(){
Assembly ass=Assembly.Load(customConfigManager.GetConfig("dbhelperReflicationKey").split(",")[1]);
Type type =ass.GetType(customConfigManager.GetConfig("dbhelperReflicationKey").split(",")[0]);
object osqlhelper=Activator.CreateInstance(type);
IDbHelper dbhelper=osqlhelper as idbhelper;
return dbhelper;
}
}
反射反射,程序员的快乐,无处不在:MVC,IOP,ORM
-------反射可以自己动态调用方法:---------------------
Assembly assem=Assembly.Load("AspNetCore.DB.SqlServer");
Type type=assem.GetType("AspNetCore.DB.SqlServer.SqlServerHelper");
object obj=Activator.CreateInstance(type);
MetchodInfo show1=type.GetMethod("show1");
//MetchodInfo show1=type.GetMethod("show3",new Type[]{typeof(int),typeof(string)});
反射可以调用重载方法:
show1.Invoke(obj,null);
show1.Invoke(obj,new object[]{123});
反射可以调用私有方法:
反射可以调用静态方法:
反射可以调用普通类中的泛型方法:延时加载
var show=type.GetMethod("show");
Methodinfo showg=show.MakeGenericMethod(new Type[]{typeof(int),typeof(string));
showg.Invoke(obj,new object[]{123,"yes“});
反射可以调用泛型类中的泛型方法且参数一致:延时加载:
Assembly assem=Assembly.Load("AspNetCore.DB.SqlServer");
Type type=assem.GetType("AspNetCore.DB.SqlServer.GenericClass`3"); //`3表示此类是带三个参数的泛型类
Type type2=type.MakeGenericType(new Type[]{new Type[]{typeof(int),typeof(string)); //调用指定泛型参数类型
var otest=Activator.CreateInstance(type2);
var show=type2.GetMethod(“show");
show.Invoke(otest,new object[]{123,345,"yes"});
反射可以调用泛型类中的泛型方法且参数不一致:
Assembly assem=Assembly.Load("AspNetCore.DB.SqlServer");
Type type=assem.GetType("AspNetCore.DB.SqlServer.GenericClass`3"); //`3表示此类是带三个参数的泛型类
Type type2=type.MakeGenericType(new Type[]{new Type[]{typeof(int),typeof(string)); //调用指定泛型参数类型
var otest=Activator.CreateInstance(type2);
var show=type2.GetMethod(“show");
var genmthod = show.MakeGenericMethod(new Type[]{typeof(int),typeof(string)});
genmthod.Invoke(otest,new object[]{123,345,"yes"});
反射缺点:
稍微影响性能;可以通过缓存来解决;
MVC框架中的反射调用:
/home/index
-------------反转在ORM框架中的应用-------------------、
Type type=typeof(People);
object opeople=Activator.CreateInstance(type);
foreach(var prop in type.GetProperties())
{
prop.name;
if(prop.name.Equals("id")){
prop.SetValue(opeople,123);
}
}
foreach(var field in type.GetFields())
{
field.name;
filed.Name = field.GetValue(opeople);
}
SqlDataReader reader=new sqlcommand.executeReader();
reader.Read();
Type type=typeof(People);
object opeople=Activator.CreateInstance(type);
foreach(var prop in type.GetProperties())
{
prop.SetValue(opeople,reader[prop.Name]);
}
--------------反射在ORM框架demo---------------
SqlServerHelper sqlhelper=new SqlServerHelper();
Company company=sqlhelper.FindCommany(1);
Company company2=sqlhelp1.Find<company>(1);
SysUser user=sqlhelp1.Find<SysUser>(1);
public class SqlServerHelper{
public T FInd<T>(int Id){
string conn="";
Type type=typeof(T);
var fields=string.Join(",",type.GetProperties().Select(p=>$"[{p.Name}]"));
var tablenName=type.Name;
var tableName=$"select {fields} from {tableName} where Id="+Id;
conn;
command;
SqlDataReader reader=new sqlcommand.executeReader();
reader.Read();
object object =Activator.CreateInstance(type);
foreach(var prop in type.GetProperties())
{
prop.SetValue(object,reader[prop.Name]);
}
return (T)object;
}
}