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的注解,要求该注解只能用于类且代码运行时该 ...
随机推荐
- [译] C# 5.0 中的 Async 和 Await (整理中...)
C# 5.0 中的 Async 和 Await [博主]反骨仔 [本文]http://www.cnblogs.com/liqingwen/p/6069062.html 伴随着 .NET 4.5 和 V ...
- 【原创经验分享】WCF之消息队列
最近都在鼓捣这个WCF,因为看到说WCF比WebService功能要强大许多,另外也看了一些公司的招聘信息,貌似一些中.高级的程序员招聘,都有提及到WCF这一块,所以,自己也关心关心一下,虽然目前工作 ...
- CRL快速开发框架系列教程六(分布式缓存解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- linux yum命令详解
yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能够从指定的服务器自动下载RP ...
- Centos 7.0 安装Mono 3.4 和 Jexus 5.6
2013-07-26 写过一篇<CentOS 6.3下 安装 Mono 3.2 和Jexus 5.4>,CentOS 7在CentOS 6的基础上有很大的调整,本文是这篇文章的更新,主要介 ...
- WPF - 属性系统 - APaas(AttachedProperty as a service)
是的,文章的题目看起来很牛,我承认. 附加属性是WPF中的一个非常重要的功能.例如在设置布局的过程中,软件开发人员就常常通过DockPanel的Dock附加属性来设置其各个子元素所处的布局位置.同样地 ...
- Lesson 20 One man in a boat
Text Fishing is my favourite sport. I often fish for hours without catching anything. But this does ...
- zone.js - 暴力之美
在ng2的开发过程中,Angular团队为我们带来了一个新的库 – zone.js.zone.js的设计灵感来源于Dart语言,它描述JavaScript执行过程的上下文,可以在异步任务之间进行持久性 ...
- 不得不知的CLR中的GC
引言 GC 作为CLR的垃圾回收器,让程序员可以把更多的关注度放在业务上而不是垃圾回收(内存回收)上.其实很多语言也有类似的东东, 如Java也有JIT 等等 GC基本概念 垃圾回收机制的算法有好多种 ...
- Tomcat服务无法启动的问题
去年下半年公司就决定投入人力物力"跟风"做大数据方向的研究并应用到后续项目中,于是乎,我们也得熟悉下Java才行了. 先弄个JavaEE的开发环境再说吧.装JDK.JRE,其实JD ...