时隔很长时间,笔者再次翻看到以前关于反射的笔记,看到了反射的基本语法,简单的应用,不禁心中还是有些许疑惑,反射到底是什么,有何作用呢?
我们知道基于C#开发的程序,编译后会生成exe/dll文件,这就是源数据清单。正常情况下,是无法直接打开查看里面的代码的。带着这样的疑问,我们来思考工作当中可能
会出现的两种情况:
1 比如另一方为你提供了编译后的程序文件dll/exe,因业务需要,你可能需要查看在这个exe/dll提供了哪些方法,或者可能需要对某些方法进行重写,那要怎么办呢?
其实我们这里就可以使用到反射,在前两节中,我们讲到,可以通过反射读取到源数清单里的信息(使用api可以遍历类中的属性、字段、方法)
2对外提供服务,未知要给谁提供服务,但是制定进入的规则。比如MVC ,建立好一个MVC项目后,我们在浏览器输入Controllers的名称/action名称 就能访问到方法。
在反射的1-2里面我们讲到过,通过如下代码,我们可以获取到指定方法,然后用Invoke实现方法的调用。而Control其实本质而言也是一个Class,Action 的本质也就是一个Method。至于MVC底层如何使用反射具体实现,
我们在这里暂且不考虑。
Assembly assembly = Assembly.LoadFrom("Business.DB.SqlServer.dll"); Type type = assembly.GetType("Business.DB.SqlServer.ReflectionTest"); object oInstance = Activator.CreateInstance(type); MethodInfo show5 = type.GetMethod("Show5");
3反射+ 配置文件+ 工厂----IOC容器的雏形;简单版本的IOC容器;(在博客AOP\IOC\依赖注入 分类中,我们会对于IOC容器进行详细的探究)
案例:通过反射、简单工厂模式、泛型、ado.net实现简易版手写ORM
注: 其实我们借助反编译工具去查看ORM的源码会发现,不管你上层如何封装,底层都是基于ADO.NET去做的
需求:1可以查询任何类型的数据(比如数据库有user表、x表、y表.....) 2具体查询语句,可以不同的表生成不同的查询语句
分析:可以采用泛型,一个方法满足多种类型的需求,具体查询语句我们一般会写成 Select x1,x2.....from tableName where x=.... 不同的表,列名以及table Name也需要根据需求来变动
SqlServerHelper sqlServer = new SqlServerHelper(); SysCompany sysCompany1 = sqlServer.Find<SysCompany>(1);
public T Find<T>(int id) where T : BaseModel { Type type = typeof(T); object oReulst = Activator.CreateInstance(type); using (SqlConnection connection = new SqlConnection(ConnectionString)) { connection.Open(); #region MyRegion //string sql = @"SELECT [Id] // ,[Name] // ,[CreateTime] // ,[CreatorId] // ,[LastModifierId] // ,[LastModifyTime] // FROM [ZhaoXiPracticeDB].[dbo].[SysCompany] where id=" + id; //这条Sql语句是干嘛的?---SysCompany专属Sql语句 //问题:需要通过泛型T 来动态的生成Sql语句 //string sql = "Select {'',''} from {表名称} where id=" + id; //需要通过泛型T 来动态的生成查询的字段,表名称 //List<string> propList = type.GetProperties().Select(c => $"[{c.Name}]").ToList(); //string props = string.Join(',', propList); #endregion //如果查询SysCompany 10 次; 每次来查询,都要生成Sql语句; //就算是查询10次,其实Sql语句都一样的;最多就是查询条件不一样 //查询10 --生成10次---都是同一个类型;---怎么优化一下? //泛型缓存:避免为了同一个类型,多次去生成Sql语句 // 提高性能 //string sql = $"Select {string.Join(',', type.GetProperties().Select(c => $"[{c.Name}]").ToList())} from {type.Name} where id=" + id; string sql = ConstantSqlString<T>.GetFindSql(id); SqlCommand sqlCommand = new SqlCommand(sql, connection); SqlDataReader reader = sqlCommand.ExecuteReader(); if (reader.Read()) { foreach (var prop in type.GetProperties()) { prop.SetValue(oReulst, reader[prop.Name] is DBNull ? null : reader[prop.Name]); } } //问题来了,数据可以查询到---需要返回一个对象--需要赋值给对象,然后返回对象;----反射 } return (T)oReulst;标签:语句,反射,string,--,查询,案例,type,id From: https://www.cnblogs.com/JohnTang/p/17017864.html