反射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();
        }
    }
}

时间: 2024-09-16 12:04:13

反射ORM的相关文章

C#基础系列:实现自己的ORM(反射以及Attribute在ORM中的应用)

反射以及Attribute在ORM中的应用 一. 反射什么是反射?简单点吧,反射就是在运行时动态获取对象信息的方法,比如运行时知道对象有哪些属性,方法,委托等等等等.反射有什么用呢?反射不但让你在运行是获取对象的信息,还提供运行时动态调用对象方法以及动态设置.获取属性等的能力.反射在ORM中有什么用呢?我这里所讨论的ORM实现是通过自定义Attribute的方式进行映射规则的描述的.但是我们并不知道具体哪个对象需要对应哪个表,并且这些对象是独立于我们的ORM框架的,所以我们只能通过自定义Attr

ORM中去除反射,添加Expression

之前接触了别人的ORM框架,感觉牛掰到不行,然后试着自己来写自己的ORM. 最初从园子里找到其他人写的反射的例子: 1 List<PropertyInfo> pis = typeof(T).GetProperties().ToList<PropertyInfo>() 2 while (dr.Read()) 3 { 4 T model = Activator.CreateInstance<T>(); 5 6 foreach (PropertyInfo propertyIn

实施 ORM 的两项要旨:泛型和反射

鄙人认为,实施 ORM 的两项要旨乃泛型和反射.下面开始看看怎么为 DAO 层添砖加瓦. 首先,在 DBAccess 基础上扩展 DBAccessORM 接口,形成基于 ORM 的数据调用. /** * 数据访问对象 * * @author Frank Cheung * */ public interface DBAccessORM extends DBAccess { /** * 查询单笔记录,返回实体 * * @param sql * 原生 SQL 语句 * @param clazz * P

反射以及Attribute在ORM中的应用

GPS平台.网站建设.软件开发.系统运维,找森大网络科技!http://cnsendnet.taobao.com来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=488 反射以及Attribute在ORM中的应用一. 反射什么是反射?简单点吧,反射就是在运行时动态获取对象信息的方法,比如运行时知道对象有哪些属性,方法,委托等等等等.反射有什么用呢?反射不但让你在运行是获取对象的信息,还提供运行时动态调用对象方法以及动态设置.获取属性等的能力.反射在

通过java反射实现简单的关于MongoDB的对象关系映射(ORM).

通过阅读MongoDB  3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射. 1.定义抽象类:AbstractMongoSession import java.util.List; import org.bson.Document; import org.bson.conversions.Bson; import com.mongodb.client.MongoCollection; import com.mo

通过反射来手写简单的ORM SQlserver

不说废话,直接上干货,如发现问题,欢迎大家指出,谢谢! //------------------------------------MySQlServerORM [简单 CURD] using System; using System.Collections.Generic; using System.Linq; namespace COMMOM { using C10.ZRF.Model.Filter; using System.Configuration; using System.Data

减少重复工作,通过泛型、反射写一个通用的Ado.net操作数据库的简单orm底层

创建一个基类BaseEntity: public class BaseEntity { [PrimaryKey] public int Id { get; set; } public DateTime CreateTime { get; set; } public Status Status { get; set; } public string Remark { get; set; } } /// <summary> /// 自增主键标识 /// </summary> publi

java-使用反射实现ORM映射

自定义两个注解 1 package com.moon.ROM; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 @Target(ElementType.FIELD) 9 @Retention(Ret

自己动手写ORM(01):解析表达式树生成Sql碎片

什么是ORM框架:   ORM即对象关系映射(Object Relational Mapping,简称ORM),是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中. 自己也用过很多ORM框架,比如微软的EF,Hibernate.轻量级一点的有Depper等等.这些框架说白了就是让我们能像操作对象那样去操作数据库. 鄙人是个比较懒的程序猿,总想这写更少的代码做更多的事情,最近不是很忙,于是