IL实现简单的IOC容器
既然了解了IL的接口和动态类之间的知识,何不使用进来项目实验一下呢?而第一反应就是想到了平时经常说的IOC容器,在园子里搜索了一下也有这类型的文章http://www.cnblogs.com/kklldog/p/3395641.html,借鉴一下前人的知识就来实现一下吧。IOC的概念就不介绍了,想了解的同学就百度一下。
一、定义接口
首先自定义两个接口和实现
public interface IAnimal { string Cat(); string Dog(); } public class Animal:IAnimal { public string Cat() { return "I Am Cat"; } public string Dog() { return "I Am Dog"; } }
IAnimal
public interface IMail { string SendMail(); string ReceiveMail(); } public class Mail:IMail { public string SendMail() { return "Success Send"; } public string ReceiveMail() { return "Success Receive"; } }
IMail
二、配置
这里我就直接写一个方法来进行配置,不再定义接口了
public Dictionary<string,string> GetAllConfig() { Dictionary<string, string> dic = new Dictionary<string, string>(); dic.Add("IOC.Interface.IMail", "IOC.Interface.Mail,IOC"); dic.Add("IOC.Interface.IAnimal", "IOC.Interface.Animal,IOC"); return dic; }
Config
三、反射实现
public static object GetInstance(string InterfaceName) { //已经存在的对象直接使用 if (dicObj.ContainsKey(InterfaceName)) { return dicObj[InterfaceName]; } var dicConfig = new Config.Config().GetAllConfig(); if (!dicConfig.ContainsKey(InterfaceName)) { throw new Exception("未配置"); } var config = dicConfig[InterfaceName]; Type taskType = Type.GetType(config); // var taskObj1 = CreateInstance(taskType); var taskObj= CreateInstanceByEmit(taskType); if (null == taskObj) throw new Exception("实例化接口错误"); dicObj.Add(InterfaceName, taskObj); return taskObj; }
GetInstance
private static Object CreateInstance(Type taskType) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); object taskObj = Activator.CreateInstance(taskType); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; string elapsedTime = String.Format("{0}",ts.Ticks ); Console.WriteLine("CreateInstance RunTime " + elapsedTime); return taskObj; }
CreateInstance
通过传入接口,再去配置列表中找到对应的实现进行实例化。如果存在就直接使用实例化后的对象
四、Emit实现
要想知道Emit是如何获取接口对应实例化的对象,可以先进行一下的尝试。比如我要获取IAnimal接口实例化的对象
public IAnimal GetInterface() { var realize= new Animal(); return (IAnimal)realize; }
通过反编译工具得到以下的IL信息
IL解释:
L_0001:创建一个新的对象(构造函数)到计算堆栈上
L_0006-L_0007:先存储到指定位置再获取推送到计算堆栈上(实现中可省略)
L_0008-L_000b:同样是先存储到指定位置再获取推送到堆栈上(实现中可省略),br.s跳转到L_000b执行(针对这段IL没必要用到这个操作)
L_000c:返回
然后我们可以通过IL代码进行实现
private static Object CreateInstanceByEmit(Type taskType) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); BindingFlags defaultFlags = BindingFlags.Public | BindingFlags.Instance; ];//获取默认构造函数 var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString("N"), typeof(Object), new[] { typeof(object[]) }, true); ILGenerator IL = dynamicMethod.GetILGenerator(); IL.Emit(OpCodes.Newobj, constructor); if (constructor.ReflectedType.IsValueType) IL.Emit(OpCodes.Box, constructor.ReflectedType); IL.Emit(OpCodes.Ret); //关联方法 var func = (Func<Object>)dynamicMethod.CreateDelegate(typeof(Func<Object>)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; string elapsedTime = String.Format("{0}", ts.Ticks); Console.WriteLine("CreateInstanceByEmit RunTime " + elapsedTime); return func.Invoke(); }
CreateInstanceByEmit
五、执行
IAnimal iMail = ServiceTaker.GetService<IOC.Interface.IAnimal>(); Console.WriteLine(iMail.Cat());
通过以上的例子算是对Emit加深一下了解,也可以了解一下IOC的实现,当然IOC还有其他东西需要注意这就不一一介绍了。有兴趣的欢迎来进行交流
=============================================================
在实例化对象过程中,发现反射执行的速度还是优于Emit的,在参考http://kb.cnblogs.com/page/171668/发现反射和Emit对比在性能上也还是有差距的。这部分了解后再分享~~~
IL实现简单的IOC容器的更多相关文章
- IoC原理-使用反射/Emit来实现一个最简单的IoC容器
从Unity到Spring.Net,到Ninject,几年来陆陆续续用过几个IoC框架.虽然会用,但也没有一直仔细的研究过IoC实现的过程.最近花了点时间,下了Ninject的源码,研究了一番,颇有收 ...
- 【最简单IOC容器实现】实现一个最简单的IOC容器
前面DebugLZQ的两篇博文: 浅谈IOC--说清楚IOC是什么 IoC Container Benchmark - Performance comparison 在浅谈IOC--说清楚IOC是什么 ...
- 比Spring简单的IoC容器
比Spring简单的IoC容器 Spring 虽然比起EJB轻量了许多,但是因为它需要兼容许多不同的类库,导致现在Spring还是相当的庞大的,动不动就上40MB的jar包, 而且想要理解Spring ...
- 几句代码简单实现IoC容器
前言 最近在调试EasyNetQ代码的时候发现里面有一段代码,就是IoC容器的简单实现,跟着他的代码敲了一遍,发现了奇妙之处.当然也是因为我才疏学浅导致孤陋寡闻了.他的思路就是通过动态调用构造函数生成 ...
- 手写一个最简单的IOC容器,从而了解spring的核心原理
从事开发工作多年,spring源码没有特意去看过.但是相关技术原理倒是背了不少,毕竟面试的那关还是得过啊! 正所谓面试造火箭,工作拧螺丝.下面实现一个最简单的ioc容器,供大家参考. 1.最终结果 2 ...
- .NET实现一个简单的IOC容器
目录 1.主要细节 2.具体示例 参考及示例代码下载 shanzm-2020年3月17日 20:06:01 1.主要细节 使用反射程序集的方式获取对象的类型 通过反射的方式获取指定类型的的所有公共属性 ...
- 自己动手实现一个简单的 IOC容器
控制反转,即Inversion of Control(IoC),是面向对象中的一种设计原则,可以用有效降低架构代码的耦合度,从对象调用者角度又叫做依赖注入,即Dependency Injection( ...
- 最简单的ioc容器代码(低仿Spring )
Spring 的一大核心就是IOC,控制反转(依赖注入). 对象交由容器去控制,降低耦合性. Spring 的ioc实现原理其实很简单,容器启动后读取并解析配置文件,根据配置文件中<bean&g ...
- 简单模拟IOC容器:返回对象并能抛出异常
本次要求:已知com.zzj.vo包下分别有Tiger.lion.Elephant三个Java源文件,请据此实现以下功能:①.自定义一个名为Component的注解,要求该注解只能用于类且代码运行时该 ...
随机推荐
- .net 分布式架构之任务调度平台
开源地址:http://git.oschina.net/chejiangyi/Dyd.BaseService.TaskManager .net 任务调度平台 用于.net dll,exe的任务的挂载, ...
- inline-block元素间距问题的几种解决方案
不知道大家有没有碰到过设置了display:inline-block;的几个相邻元素之间有几px间距的问题,这里提供几种简单实用的解决方法,希望能够帮到大家! 方法1. 将<li>标签 ...
- Lind.DDD.Aspects通过Plugins实现方法的动态拦截~Lind里的AOP
回到目录 .Net MVC之所以发展的如些之好,一个很重要原因就是它公开了一组AOP的过滤器,即使用这些过滤器可以方便的拦截controller里的action,并注入我们自己的代码逻辑,向全局的异常 ...
- SharePoint 2016 入门视频教程
之前一直有朋友让自己录一些SharePoint的入门视频,之前没有太多时间,一个巧合的机会收到CSDN学院的邮件,可以在CSDN上发布视频教程,自己就录了一些.说起录视频也是蛮辛苦的,每天下班吃完饭要 ...
- 深入理解 Android 之 View 的绘制流程
概述 本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定 ...
- Linux基础介绍【第一篇】
Linux简介 什么是操作系统? 操作系统,英文名称Operating System,简称OS,是计算机系统中必不可少的基础系统软件,它是应用程序运行以及用户操作必备的基础环境支撑,是计算机系统的核心 ...
- IIS启动失败,启动Windows Process Activation Service时,出现错误13:数据无效 ;HTTP 错误 401.2 - Unauthorized 由于身份验证头无效,您无权查看此页
因为修改过管理员账号的密码后重启服务器导致IIS无法启动,出现已下异常 1.解决:"启动Windows Process Activation Service时,出现错误13:数据无效&quo ...
- (转载) RESTful API 设计指南
作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...
- TFS 生成配置
生成
- CentOS7 + mono +Jexus 环境的搭建
CentOS7的安装和配置 1,从http://www.centos.org/下载CentOS7的镜像,并在VMWare中创建该镜像的虚拟机,为方便操作,把虚拟机的网络连接设置为桥接模式:在安装过程中 ...