反射与IOC
反射
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的以及动态调用对象的方法的功能称为反射机制。反射机制动态获取方法并使用方法和自己直接创建一个类的对象去直接调用时完全不一样的。比如一个类里面有一个属性为private的属性或者方法,我们是不能直接去调用的,但是可以使用反射机制去动态调用。
IOC
IOC最大的好处是把对象生成放在了XML里定义,所以当我们需要换一个实现子类将会变成很简单(一般这样的对象都是实现于某种接口的),只要修改XML就可以了,这样我们甚至可以实现对象的热插拨(有点象USB接口和SCSI硬盘了)。在不适用IOC之前一个对象如果依赖于另一个对象(后面我们简称依赖对象和被依赖对象),我们要在依赖对象中实例化一个被依赖对象,这样才能调用被依赖对象中的方法。显然这样耦合度比较高,不符合我们编程的原则。因此这时候我们就会引入一个第三方对象,它负责给依赖对象直接输送一个被依赖对象,降低二者之间的耦合性。下图是加入IOC容器前后,系统中对象耦合度的对比
软件系统在没有引入IOC容器之前,如图1所示,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。
软件系统在引入IOC容器之后,这种情形就完全改变了,如图2所示,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。
通过前后的对比,我们不难看出来:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。
实例
反射实例代码
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#666666;"><strong>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace StudentDAL { public class Student { //属性 public string Name{get;set;} public int Age { get; set; } //无参数构造函数 public Student() { this.Name = "无参数"; this.Age = 0; } //有参数构造函数 public Student(string name, int age) { this.Name = "name"; this.Age = age; } //public带参带返回值函数 public string PublishMethodReturn() { return string.Format("我叫"+Name+"年龄" +Age); } } }</strong></span>
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#666666;"><strong>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection; namespace ITOO_Reflection { class Program { static void Main(string[] args) { //使用 Assembly 定义和加载程序集, //加载在程序集清单中列出的模块, //以及从此程序集中查找类型并创建该类型的实例. //获取程序集 Assembly assembly = Assembly.Load("StudentDAL"); //从程序及获取指定对象类型 Type type = assembly.GetType("StudentDAL.Student"); var instance = assembly.CreateInstance("StudentDAL.Student"); //为学生类的属性赋值 type.GetProperty("Name").SetValue(instance, "shx", null); type.GetProperty("Age").SetValue(instance, 18, null); //获取Student类的方法 var method = type.GetMethod("PublishMethodReturn"); //调用Student类的成员方法PublishMethodReturn var S= method.Invoke(instance, null); Console.WriteLine(S); Console.Read(); } } }</strong></span>
运行结果
IOC实例代码
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#666666;"><strong>using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ITOO.IOC.IDAL { public interface IUserDal { void HelloWord(); } } </strong></span>
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#666666;"><strong>using System; using System.Collections.Generic; using System.Linq; using System.Text; using ITOO.IOC.IDAL; namespace ITOO.IOC.DAL { public class User:IUserDal { public void HelloWord() { Console.WriteLine("helloword"); } } } </strong></span>
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#666666;"><strong>using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ITOO.IOC.IBLL { public interface IUserBll { void HelloWord(); } } </strong></span>
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#666666;"><strong>using System; using System.Collections.Generic; using System.Linq; using System.Text; using ITOO.IOC.IBLL; using ITOO.IOC.IDAL; using ITOO.Library.Core.AOP; namespace ITOO.IOC.BLL { public class UserBll:IUserBll { public void HelloWord() { //使用底层封装的SpringHelper从IOC容器中拿到D层的类的对象实例 IUserDal iuser = SpringHelper.GetObject<IUserDal>("User"); iuser.HelloWord(); } } } </strong></span>
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#666666;"><strong>using System; using System.Collections.Generic; using System.Linq; using System.Text; using ITOO.IOC.IBLL; using ITOO.Library.Core.AOP; namespace ITOO.IOC.Client { class Program { static void Main(string[] args) { //客户端通过底层封装的SpringHelper从IOC容器中根据B层类的对象的id拿到UserBll类的实例 IUserBll iuserbll = SpringHelper.GetObject<IUserBll>("UserBll"); //调用UserBll类的方法 iuserbll.HelloWord(); Console.Read(); } } } </strong></span>
运行结果
以上就是反射与IOC的内容,更多相关内容请关注PHP中文网(www.php.cn)!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

反射机制允许程序在运行时获取和修改类信息,它可用于实现接口和抽象类的反射:接口的反射:通过Class.forName()获取接口反射对象,访问其元数据(名称、方法和字段)。抽象类的反射:与接口类似,可获取抽象类的反射对象,访问其元数据以及非抽象方法。实战案例:反射机制可用于实现动态代理,通过动态创建代理类在运行时拦截对接口方法的调用。

Go语言中可以使用反射来访问私有字段和方法:访问私有字段:通过reflect.ValueOf()获取值的反射值,再使用FieldByName()获取字段的反射值,并调用String()方法打印字段的值。调用私有方法:同样通过reflect.ValueOf()获取值的反射值,再使用MethodByName()获取方法的反射值,最后调用Call()方法执行方法。实战案例:通过反射修改私有字段值和调用私有方法,实现对对象的控制和单元测试覆盖。

反射在Go中提供类型检查和修改功能,但存在安全隐患,包括任意代码执行、类型伪造和数据泄露。最佳方案包括限制反射权限、操作、使用白名单或黑名单、验证输入以及使用安全工具。实践中,反射可安全用于检查类型信息。

Go语言反射允许在运行时操控变量值,包括修改布尔值、整数、浮点数和字符串。通过获取变量的Value,可以调用SetBool、SetInt、SetFloat和SetString方法进行修改。例如,可以解析JSON字符串为结构体,然后使用反射修改结构体字段的值。需要注意,反射操作较慢,且无法修改不可修改字段,修改结构体字段值时可能不会自动更新相关字段。

Go语言中的反射功能允许程序在运行时检查和修改类型的结构。通过使用Type、Value和reflect.Kind,我们可以获取对象的类型信息、字段值和方法,还可以创建和修改对象。具体的操作方法包括:检查类型(TypeOf())、获取字段值(ValueOf()、FieldByName())、修改字段值(Set())、创建对象(New())。

控制反转是一种设计模式,将对象创建和依赖关系管理从客户端代码转移到容器中,提高代码灵活性和可测试性。Go语言中IOC的实现可以使用wire框架,具体步骤包括:定义接口、定义类型、使用wire函数。通过使用wire生成的容器,可以获得提高可测试性、灵活性以及简化配置的优点。

利用反射,Go允许创建新类型,1.使用reflect.TypeOf()获取现有类型的reflect.Type值;2.使用reflect.New()创建新类型的指针值;3.通过*Ptr.Elem()访问实际值;4.反射还可以根据字符串动态创建新类型,用于构建灵活且动态的程序。

Java中使用反射机制实现方法重载:通过反射获取方法:使用getMethod()方法获取方法对象,指定方法名和参数类型。调用方法:使用invoke()方法调用方法,指定调用者对象和参数值。
