• 反射基础


    反射概念反射是由框架提供的一个类库,可以访问dll的metadata,获取的dll的信息,并使用它
    反射的命名空间:using System.Reflection;
    DLL里面包含了两种:
    1.IL中间语言,最后变成机器码
    2.metadata元数据,用于描述IL
    程序结构:
    Reflence引用DB.sqlserver DB.interface
    DB.sqlserver引用DB.interface
    接口配置:
    普通实现方法:实例化
    IDBserver dBserver =newsqlserverDBhelper();
    dBserver.Query();
    效果
    利用反射去实现:
    //Assembly是反射的命名空间引入的类
    Assembly assembly = Assembly.Load("DB.sqlserver");//动态加载dll没有后缀
    Type type = assembly.GetType("DB.sqlserver.sqlserverDBhelper");//获取类型名称 传递完整类型
    Object obj = Activator.CreateInstance(type);//创建对象
    ((sqlserverDBhelper)obj).Query();//调用方法
    Console.ReadLine();
    如果每增加一个类就要重新指定DLL名称,配置性不高
    为了增加程序的可配置性,新建一个工厂类
    如果程序需要读取配置文件就需要引入一个DLL
    引入命名空间 using System.Configuration;
    配置文件添加,键值对
    <appSettings>
    <add key="IDBHelperType" value="DB.sqlserver,DB.sqlserver.sqlserverDBhelper"></add>
    </appSettings>
    publicclassObjectFactroy
    {
    //根据key名字获取,读取到当前项
    privatestatic string IDBHelperType = ConfigurationManager.AppSettings["IDBHelperType"];
    publicstatic string DLLName = IDBHelperType.Split(',')[0];//获取DLL名称
    publicstatic string TypeName = IDBHelperType.Split(',')[1];//获取文件名
    publicstatic IDBserver CreateInstance()
    {
                Assembly assembly = Assembly.Load(DLLName);
                Type type = assembly.GetType(TypeName);//获取类型名称 传递完整类型
                Object obj = Activator.CreateInstance(type);//创建对象
    return(IDBserver)obj;
    }
    }
    有需要变更直接在配置文件更改value值
    Main 函数调用
    IDBserver bserver = ObjectFactroy.CreateInstance();
    bserver.Query();
    1.怎样让程序可配置可扩展呢,在不改变原来代码的条件下增加一个类库
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using DB.Interface;
    namespace DB.Oracle
    {
    publicclassOracleDBhelper: IDBserver
    {
    publicOracleDBhelper()
    {
                Console.WriteLine("{0}被构造",this.GetType().Name);
    }
    publicvoidQuery()
    {
                Console.WriteLine("{0},Query",this.GetType().Name);
    }
    }
    }
    修改配置文件指向新的DLL
     
    上述已经配置好接口类型,第三方依赖注入的容器会帮你完成创建
    实际上这就是IOC,业务逻辑层提供一个接口进行IOC的配置
    此时
    1.去掉接口,反射调用方法
    此时调用的是Query的无参数构造方法
    Assembly assembly = Assembly.Load("DB.sqlserver");//动态加载dll没有后缀
    Type type = assembly.GetType("DB.sqlserver.sqlserverDBhelper");//获取类型名称 传递完整类型
    Object obj = Activator.CreateInstance(type);//创建对象
    MethodInfo method = type.GetMethod("Query",newType[]{});
    method.Invoke(obj,newobject[]{});
    仔细观察发现这也是MVC方法响应的原理,DLL在程序最初已经编译好,MVC路径:/控制器/方法。只需要指定方法就能随意跳转页面
    模仿控制器传入方法的多种参数
     Assembly assembly = Assembly.Load("DB.sqlserver");//动态加载dll没有后缀
                Type type = assembly.GetType("DB.sqlserver.sqlserverDBhelper");//获取类型名称 传递完整类型
                Object obj = Activator.CreateInstance(type);//创建对象
    {
    {
                        MethodInfo method = type.GetMethod("Query",newType[]{});
                        method.Invoke(obj,newobject[]{});
    }
    {
                        MethodInfo method = type.GetMethod("Query",newType[]{typeof(string)});
                        method.Invoke(obj,newobject[]{"AB"});
    }
    {
                        MethodInfo method = type.GetMethod("Query",newType[]{typeof(int)});
                        method.Invoke(obj,newobject[]{20});
    }
    {
                        MethodInfo method = type.GetMethod("Query",newType[]{typeof(string),typeof(int)});
                        method.Invoke(obj,newobject[]{"AB",20});
    }
    {
                        MethodInfo method = type.GetMethod("Query",newType[]{typeof(int),typeof(string)});
                        method.Invoke(obj,newobject[]{20,"AB"});
    }
    }
    反射最大的优点:动态加载、不需要引用命名空间
    缺点:编写麻烦,避开了编译器的检查不到错误
    利用反射获取属性和方法
    写死的方法:
    People people =newPeople()
    {
         id=10,
         Name="YLC"
    };
    people.Property ="字段";
    Console.WriteLine("id:{0}",people.id);
    Console.WriteLine("Name:{0}", people.Name);
    Console.WriteLine("Property:{0}", people.Property);
     
     
    这个时候如果增加一个属性,代码又需要修改,增加100个就要打印100 Console.WriteLine();
    利用反射自带的进行实现
     Type type =typeof(People);
    foreach(var item in type.GetProperties())//获取属性
    {
                    object obj = item.GetValue(people);
                    Console.WriteLine("{0}:{1}",item.Name,obj);
    }
    
    foreach(var item in type.GetFields())//获取字段
    {
                    object obj = item.GetValue(people);
                    Console.WriteLine("{0}:{1}", item.Name, obj);
    }
    效果相同

     

  • 相关阅读:
    存储类&作用域&生命周期&链接属性
    关于mysql数据库的备份和还原
    Centos 7下mysql的安装与配置
    基于Apache+php+mysql的许愿墙网站的搭建
    关于php留言本网站的搭建
    linux下面桌面的安装
    时间同步ntp服务的安装与配置
    通过挂载系统光盘搭建本地yum仓库的方法
    linux系统root用户忘记密码的重置方法
    linux系统的初化始配置
  • 原文地址:https://www.cnblogs.com/cg-ww/p/13099450.html
Copyright © 2020-2023  润新知