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的注解,要求该注解只能用于类且代码运行时该 ...
随机推荐
- 利用Node.js的Net模块实现一个命令行多人聊天室
1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...
- Hawk 6. 高级话题:子流程系统
子流程的定义 当流程设计的越来越复杂,越来越长时,就难以进行管理了.因此,采用模块化的设计才会更加合理.本节我们介绍子流程的原理和使用. 所谓子流程,就是能先构造出一个流程,然后被其他流程调用.被调用 ...
- ASP.NET WebApi OWIN 实现 OAuth 2.0
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth 允许用户提供一个令牌, ...
- MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决
一.简介 MySQL是最流行的开放源码SQL数据库管理系统,它是由MySQL AB公司开发.发布并支持的.有以下特点: MySQL是一种数据库管理系统. MySQL是一种关联数据库管理系统. MySQ ...
- 使用NUnit为游戏项目编写高质量单元测试的思考
0x00 单元测试Pro & Con 最近尝试在我参与的游戏项目中引入TDD(测试驱动开发)的开发模式,因此单元测试便变得十分必要.这篇博客就来聊一聊这段时间的感悟和想法.由于游戏开发和传统软 ...
- Oracle 分页
--1:无ORDER BY排序的写法.(效率最高) --(经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然!) SELECT * FROM (SELECT ...
- x01.os.22: ubuntu 常用设置
新组装了个 64 位电脑,i5 CPU,进入 ubuntu 后,又是一通搜索设置,整理如下,以备后用. 安装 .dep 包 sudo dpkg -i [filename.dep] 在 ubuntu 中 ...
- 为支持ASP.NET5跨平台,Jexus再添新举措
Jexus作为一款运行于Linux/FreeBSD平台上,以支持ASP.NET著称的高性能HTTP服务器和反向代理服务器,继5.6版完成对OWIN标准应用的支持后,就把着力点放到了对ASP.NET5的 ...
- Spring Boot -- Start Up
做Java Web的同学,都知道项目启动需要放到servlet容器里面运行,无论是使用哪一款IDE,都是非常麻烦的一件事情.在很早之前,一个servlet容器下可以放下很多的项目,并一起运行,而到现在 ...
- Windows 2008 R2 安装sp1时未知错误的解决办法
最近在为Windows Server 2008 R2 打sp1补丁时出现“发生未知错误”,详细信息错误:0x800f0818: google后找到解决问题步骤,参照:http://www.wikiho ...