反射ORM
七章 反射
1节
获取dll文件中的type-----------------------------------------------------------------------------------------------------------------------(*)
//程序集
程序集是.net中的概念,.dll和.exe都属于程序集
AssemblyInfo.cs是当前程序集的一些信息(版本号)
程序集包含:类型元数据(描述在代码中定义的每一类型和成员,二进制形式)、程序集元数据(程序集清单、版本号、名称等)、IL代码(这些都被装在exe或dll中)、资源文件。
每个程序集都有自己的名称版本等信息。这些信息通过AssemblyInfo.cs文件来自己定义。
//程序集得好处:
程序中只引用必须的程序集,减小程序的尺寸。
程序集可以封装一些代码,只提供必要的访问接口。
//反射
反编译工具和智能提示都是通过反射来实现的。
反射:动态获取程序集中的元数据来操作类型的
Type类是实现反射的一个重要的类,通过它我们可以获取类中的所有的信息,包括方法、属性等。可以动态调用属性和方法。Type是对类的描述
//如何获取一个类中的所有属性
//在本类中
//1
//Type tp = typeof(Person); //获得当前程序集指定公共类----------------------------(*)
//2
Person per = new Person();
Type tp = per.GetType();//也可以获得当前实例的公共类---------------------------(*)
MethodInfo[] methes = tp.GetMethods(); //获得当前公共类的所有公共方法
for (int i = 0; i < methes.Length;i++ )
{
Console.WriteLine(methes[i].Name);
}
PropertyInfo[] ps = tp.GetProperties();//获得当前公共类的所有公共属性
foreach(PropertyInfo p in ps)
{
Console.WriteLine(p.Name);
}
MyClass类库 (不需要引用,直接获得程序集)
//在外部类中
string path = @"G:\RuPeng_YZK_150107\Console_NETStronger_Chapter_7\MyClasses\bin\Debug\MyClasses.dll";
Assembly ass = Assembly.LoadFile(path);//加载指定路径上的程序集信息文件------------(*)
Type[] tps = ass.GetExportedTypes();//获得此程序集信息中定义的类型--------------(*)
foreach(Type tp in tps)
{
//Console.WriteLine(tp.Name);
MethodInfo[] methes = tp.GetMethods(); //获得该公共类中的所有方法
foreach (MethodInfo meth in methes)
{
Console.WriteLine(meth.Name);
}
}
2节
三个比较重要的方法------------------------------------------------------------------------------------------------------(*)
//第二中获得程序集的所有公共类型,指定公共类型
string path = @"G:\RuPeng_YZK_150107\Console_NETStronger_Chapter_7\MyThreeClasses\bin\Debug\MyThreeClasses.dll";
Assembly ass = Assembly.LoadFile(path);//从指定程序集路径获得程序集
Type tpPerson = ass.GetType("MyThreeClasses.Person");//获得指定的程序集类型名称的类型实例
Type tpStudent = ass.GetType("MyThreeClasses.Student");
//Console.WriteLine(tp.Name);
bool flag = tpPerson.IsAssignableFrom(tpStudent);//当前类型的实例是否可以用指定类型的实例进行赋值--true
bool flag1 = tpStudent.IsAssignableFrom(tpPerson);//false--因为Student是Person的子类
bool flag2 = tpPerson.IsSubclassOf(tpStudent);//当前类是否是指定类派生的,即是否是指定类的子类
bool flag3 = tpStudent.IsSubclassOf(tpPerson);
object obj = Activator.CreateInstance(tpStudent);//创建指定类型的一个实例
bool flag4 = tpPerson.IsInstanceOfType(obj);//指定对象是否是当前类的实例
Type tpAnimal = ass.GetType("MyThreeClasses.Animal");
bool flag5 = tpAnimal.IsAbstract;//属性,指定类是否是抽象类
Console.WriteLine(flag5);
3节
动态调用程序集中的方法------------------------------------------------------------------------------------------------(*)
//动态调用(dynamic call)
//需要先获得类型的方法,然后再调用这个方法
//Person per = new Person();
//Type tp = per.GetType();
Type tp = typeof(Person);
MethodInfo meth = tp.GetMethod("SayHello",new Type[]{typeof(string)});//获得这个类型中指定名称的公共方法
object obj = Activator.CreateInstance(tp); //创建一个指定类型的实例
meth.Invoke(obj,new object[]{"....很想"}); //使用指定参数调用当前实例的方法 //没有参数就是null
Console.ReadKey();
class Person
{
public void SayHello(string str)
{
Console.WriteLine("hello,想我了吗?"+str);
}
}
4节
反射插件(Reflecting the plug-in)----------------------------------------------------------------------------------------(*)
//做一个小写转大写的插件
主程序--->搜索dll文件
获得所有程序集
获取Type
是否实现了插件的规范(用接口方式命名这个接口)
菜单(文件 编辑 视图 帮助)
TextBox(Dock)
//寻找当前程序集路径,在其所在目录的文件下,搜索指定程序集dll
//主程序
//窗口加载时,添加插件Editplus
private void Form1_Load(object sender, EventArgs e)
{
//获得插件的路劲
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Lib");
//搜索目录中与指定模式匹配的文件集dll文件
string[] files = Directory.GetFiles(path, "*.dll");
foreach(string file in files)
{
//加载指定路径中程序集的内容
Assembly ass = Assembly.LoadFile(file);
//获得该程序集中所有的类型
Type[] tps = ass.GetTypes();
//获得接口的类型
Type ieditplus = typeof(IEditplus);
//插件程序集的所有类型中实现接口的类型
foreach(Type tp in tps)
{
//如果接口类型的实例可以由某一类型的实例赋予,且这一类型又不是抽象类,就可以创建这一类型的实例,去实例化获得这个接口
if(ieditplus.IsAssignableFrom(tp) && !tp.IsAbstract )
{
IEditplus iedit = (IEditplus)Activator.CreateInstance(tp);
//这个接口的插件名称就可以附加到菜单的下拉项中
ToolStripItem tsi = tsmView.DropDownItems.Add(iedit.Name);
//菜单下拉项tsi的点击事件,执行接口中的"小写转大写方法",所以需要传接口,可以用控件的tag存接口
tsi.Tag = iedit;//可以用当前点击控件的tag存接口
tsi.Click += new EventHandler(tsi_Click);
}
}
}
}
private void tsi_Click(object sender, EventArgs e)
{
//需要获得当前控件
ToolStripItem tsi = sender as ToolStripItem;
//需要获得这个接口
IEditplus iedit = tsi.Tag as IEditplus;
//需要执行接口中的方法
txt.Text = iedit.LittleToLarge(txt);
}
//插件的接口类---(主程序和子程序都需要添加对接口的引用)
namespace ClassLibary_Notice
{
public interface IEditplus
{
string Name { get; } //这个插件 接口的名称,是只读、不能修改的
string LittleToLarge(TextBox tb); //插件 接口中的小写转大写方法---文本框需要添加System.Windows.Forms的引用
}
}
//插件(接口类的子类,子程序)---(需要把插件放入主程序的Lib中,使主程序可以找到实现了接口的类型)
namespace ClassLibrary_Notice_Substring.cs
{
public class Editplus:IEditplus
{
public string Name
{
get { return "小写转大写"; }
}
public string LittleToLarge(System.Windows.Forms.TextBox tb)
{
return tb.Text.ToUpper();
}
}
}
反射ORM的更多相关文章
- 反射ORM 三层(for oracle)
sql server and oracle 不同之处只在于: 1·参数@和: 2·自增和序列 3·oracle使用了存储过程以获得当前插入数据的ID DAL层的ORM using Oracle.Dat ...
- 反射ORM 三层(for sql server/mysql)
sql server and oracle 不同之处只在于: 1·参数@和: 2·自增和序列 RPROM.cs //(写错愕,应该是RPORM) RPROM.Insert(p1); //需求:DBS中 ...
- orm 小结
1. 销售注册,登录系统 - 用户表 2.销售添加客户信息,成为销售的私户 - 客户表 3. 销售固定时间跟进客户 - 跟进记录表 4. 客户报名 - 报名记录表 - 班级表(必须 ...
- 巨蟒django之CRM3 添加和编辑客户&&公户和私户的展示和转换
昨日内容回顾: day66 1. 内容回顾 1. 数据的展示 数据通过ORM查询出来 对象列表 QuerySet 1. 普通的字段 对象.字段名 ——> 数据库中的值 2. choices (( ...
- 一头扎进 JAVA
硅不可 吉米 JAVA 基础 -- 基础不牢,地动山摇 子类应该比 父类更为 开放 (public protected default private) 子类方法不能比父类抛出更高异常( 可以为父类方 ...
- ORM框架通过映射(反射)获取数据库的数据
ORM(Object Relational Mapping)框架采用元数据来描述对象一关系映射细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中.只要提供了持久化类与表的映射关系,ORM ...
- C#基础系列:实现自己的ORM(反射以及Attribute在ORM中的应用)
反射以及Attribute在ORM中的应用 一. 反射什么是反射?简单点吧,反射就是在运行时动态获取对象信息的方法,比如运行时知道对象有哪些属性,方法,委托等等等等.反射有什么用呢?反射不但让你在运行 ...
- ORM中去除反射,添加Expression
之前接触了别人的ORM框架,感觉牛掰到不行,然后试着自己来写自己的ORM. 最初从园子里找到其他人写的反射的例子: List<PropertyInfo> pis = typeof(T).G ...
- 利用抽象、多态实现无反射的绿色环保ORM框架
最近一直在忙新公司的基础库建设,对系统架构.开发框架及快速开发平台的设计实施都积累了一定的实践经验. 一般的中小型的软件开发公司,如果按照技术储备来衡量软件项目的技术含量的评定依据是可行的.但如果光是 ...
随机推荐
- for循环执行流程
语句格式: for(表达式1;表达式2;表达式3) { 循环体 } 表达式1:赋值表达式,用来给控制变量赋初值.(只执行一次) 表达式2:逻辑表达式,是循环的控制条件,用来判断控制变量是否符合循环条件 ...
- 斯坦福机器学习视频笔记 Week6 关于机器学习的建议 Advice for Applying Machine Learning
我们将学习如何系统地提升机器学习算法,告诉你学习算法何时做得不好,并描述如何'调试'你的学习算法和提高其性能的“最佳实践”.要优化机器学习算法,需要先了解可以在哪里做最大的改进. 我们将讨论如何理解具 ...
- JAVAWeb学习总结(一)
一.基本概念 1.1.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 静态web资源( ...
- C++使用命名空间中成员的三种方式
通过简单的代码来介绍使用命名空间中成员的三种方式(我们最常用到的命名空间是是标准库std,下面的命名空间都以std为例): 使用作用域符:: #include<iostream> int ...
- echache缓存的简单使用方法
1.需要echache的jar包 2.需要配置文件ehcache.xml和ehcache.xsd,主要是在ehcache.xml中进行配置 3.修改配置文件ehcache.xml ,例如添加配置如下 ...
- QT 带有菜单项的ToolButton
QToolBar *pToolBar = new QToolBar; QToolButton *pMenuBtn = new QToolButton; pMenuBtn->setText(tr( ...
- linux图形界面基本知识(X、X11、Xfree86、Xorg、GNOME、KDE之间的关系)
linux图形界面基本知识(X.X11.Xfree86.Xorg.GNOME.KDE之间的关系)(转自互联网) LINUX初学者经常分不清楚linux和X之间,X和Xfree86之间,X和KDE,GN ...
- ajax设置Access-Control-Allow-Origin实现跨域访问
ajax跨域访问 1.jsonp方法,jsonp方法是一种非官方方法,这种方法只支持GET方式, 不如POST方式安全.(即使使用jquery的jsonp方法,type设为POST, 也会自动变为GE ...
- Java中初始变量默认值
Java语言中有8种基本数据类型,基本情况汇总如下: 序号 数据类型 大小/位 封装类 默认值 可表示数据范围 1 byte(位) 8 Byte 0 -128~127 2 short(短整数) 16 ...
- Myeclipse快捷键(二)
Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D: 删除当前行Ctrl+Alt+↓ 复制当前行到下一行(复制增加) Ctrl+Alt+↑ 复制当前行到上一行(复制增加) Alt+↓ ...