shanzm-2020年3月17日 20:06:01

0.关于IOC

相关概念类知识,可以参考:

.NET中的控制反转及AutoFac的简单说明


1.主要细节

  • 使用反射程序集的方式获取对象的类型

  • 通过反射的方式获取指定类型的的所有公共属性

  • 通过特性的方式筛选需要注入对象的类型

  • 递归的方式为属性注入依赖对象

  • TODO:循环依赖、生命周期、实例作用域


2.具体示例

2.0 设计思路

  • 首要,用什么存储对象,即什么是对象容器?Dictionary类型做容器

  • 其次,怎么获取对象的类型?反射程序集

  • 再次,怎么筛选对象类型?使用特性

  • 最后,怎么实现属性注入?递归

2.1 实现IOCFac.cs

    public class IOCFactory
{ // IOC容器(创建的对象的容器)
// string key:对象类型名
// object value:对象实例
private Dictionary<string, object> iocDictionaries = new Dictionary<string, object>(); // IOC中对象类型的容器
// string key:类型名
// Type value:类型
private Dictionary<string, Type> iocTypeDictionaries = new Dictionary<string, Type>(); //加载程序集,将含有我们自定义的特性标签的类的类型存储到类型容器中
public void LoadAssmaly(string asmName)
{
Assembly assembly = Assembly.Load(asmName); Type[] types = assembly.GetTypes();//注意这里获取的是程序集中的所有定义的类型 // 筛选出含有IOcServiceAttribute特性标签的类,存储其type类型
foreach (Type type in types)
{
IOCServiceAttribute iOCService = type.GetCustomAttribute(typeof(IOCServiceAttribute)) as IOCServiceAttribute;//获取类上的自定义的特性标签
if (iOCService != null)//如果是IOCServiceAttribute标注类,则把其类型存入类型容器中
{
iocTypeDictionaries.Add(type.Name, type);//最终其中的数据:{[Student, MyIOC.ClassLib.Student],[Teacher, MyIOC.ClassLib.Teacher]}
}
} } // ioc容器对象创建
public object GetObject(string typeName)
{
//根据参数取出指定的type
Type type = iocTypeDictionaries[typeName]; //创建type类型的对象
object objectValue = Activator.CreateInstance(type); //获取type类型对象的所有属性
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
//获取类中属性上的自定义IOCInjectAttribute特性标签
IOCInjectAttribute iOCInject = (IOCInjectAttribute)propertyInfo.GetCustomAttribute(typeof(IOCInjectAttribute));
//如果该属性是含有IOCInjectAttribute类型的特性,则为其也创建一个指定的实例(即注入依赖对象)
if (iOCInject != null)
{
//为objectValue的propertyInfo属性赋值
//这里使用了递归的方式创建一个指定类型的实例
propertyInfo.SetValue(objectValue, GetObject(propertyInfo.PropertyType.Name));
}
} //将创建的对象存储到容器中
iocDictionaries.Add(typeName, objectValue); return objectValue;
} }

2.2 创建测试类和特性类

新建两个特性类:

// IOC容器类特性
// 标记了IOCServiceAttribute特性的类,被注册到容器
[AttributeUsage(AttributeTargets.Class)]//表示该自定义的属性只能用于类之上
public class IOCServiceAttribute : Attribute
{
public IOCServiceAttribute()
{
}
}
// IOC依赖注入特性
// 标明IOCInjectAttribute特性的属性,被注入
[AttributeUsage(AttributeTargets.Property)]//表示该自定义的属性只能用于类之上
public class IOCInjectAttribute : Attribute
{
public IOCInjectAttribute()
{
}
}

新建两个含有自定义特性的类

[IOCService]
public class Student
{
[IOCInject]
public Teacher Teacher { set; get; } public void Study()
{ Teacher.Teach(); Console.WriteLine($"学生:学习中……");
}
}
[IOCService]
public class Teacher
{
//[IOCInject]
//public Student _Student { set; get; }
public void Teach()
{
Console.WriteLine($"老师:教学中……");
}
}

2.3 运行测试

static void Main(string[] args)
{
IOCFactory iOCFactory = new IOCFactory();
iOCFactory.LoadAssmaly("MyIOC"); Student student = (Student)iOCFactory.GetObject("Student");
//student.Teacher = teacher;//不需要在为属性赋值,IOCFactory实现了属性的注入
student.Study();
Console.ReadKey();
}

运行结果:

老师:教学中……

学生:学习中……


参考及示例代码下载

.NET实现一个简单的IOC容器的更多相关文章

  1. 自己动手实现一个简单的 IOC容器

    控制反转,即Inversion of Control(IoC),是面向对象中的一种设计原则,可以用有效降低架构代码的耦合度,从对象调用者角度又叫做依赖注入,即Dependency Injection( ...

  2. laravel学习:php写一个简单的ioc服务管理容器

    php写一个简单的ioc服务管理容器 原创: 陈晨 CoderStory 2018-01-14 最近学习laravel框架,了解到laravel核心是一个大容器,这个容器负责几乎所有服务组件的实例化以 ...

  3. 几句代码简单实现IoC容器

    前言 最近在调试EasyNetQ代码的时候发现里面有一段代码,就是IoC容器的简单实现,跟着他的代码敲了一遍,发现了奇妙之处.当然也是因为我才疏学浅导致孤陋寡闻了.他的思路就是通过动态调用构造函数生成 ...

  4. IoC原理-使用反射/Emit来实现一个最简单的IoC容器

    从Unity到Spring.Net,到Ninject,几年来陆陆续续用过几个IoC框架.虽然会用,但也没有一直仔细的研究过IoC实现的过程.最近花了点时间,下了Ninject的源码,研究了一番,颇有收 ...

  5. 【最简单IOC容器实现】实现一个最简单的IOC容器

    前面DebugLZQ的两篇博文: 浅谈IOC--说清楚IOC是什么 IoC Container Benchmark - Performance comparison 在浅谈IOC--说清楚IOC是什么 ...

  6. 手写一个最简单的IOC容器,从而了解spring的核心原理

    从事开发工作多年,spring源码没有特意去看过.但是相关技术原理倒是背了不少,毕竟面试的那关还是得过啊! 正所谓面试造火箭,工作拧螺丝.下面实现一个最简单的ioc容器,供大家参考. 1.最终结果 2 ...

  7. (2)自己写一个简单的servle容器

    自己写一个简单的servlet,能够跑一个简单的servlet,说明一下逻辑. 首先是写一个简单的servlet,这就关联到javax.servlet和javax.servlet.http这两个包的类 ...

  8. 比Spring简单的IoC容器

    比Spring简单的IoC容器 Spring 虽然比起EJB轻量了许多,但是因为它需要兼容许多不同的类库,导致现在Spring还是相当的庞大的,动不动就上40MB的jar包, 而且想要理解Spring ...

  9. 一个简单的servlet容器

    [0]README 0.1)本文部分文字转自 “深入剖析Tomcat”,旨在学习  一个简单的servlet容器  的基础知识: 0.2)for complete source code, pleas ...

随机推荐

  1. deeplearning.ai 神经网络和深度学习 week3 浅层神经网络

    1. 第i层网络 Z[i] = W[i]A[i-1] + B[i],A[i] = f[i](Z[i]). 其中, W[i]形状是n[i]*n[i-1],n[i]是第i层神经元的数量: A[i-1]是第 ...

  2. 使用框架结构之frameset

    首先,我希望在你的目录下,有4个网页,各自显示不同的内容. 如图所示: 1.html显示"火影忍者" 2.html显示"英雄联盟" 3.html显示" ...

  3. android高仿抖音、点餐界面、天气项目、自定义view指示、爬取美女图片等源码

    Android精选源码 一个爬取美女图片的app Android高仿抖音 android一个可以上拉下滑的Ui效果 android用shape方式实现样式源码 一款Android上的新浪微博第三方轻量 ...

  4. Linux和git使用

    一.Linux ​ cd . .. - ~ ls -a h l 通配符 mkdir bouch nano vim cat clear cp -r ./db/ ./lib/ mv -r rm -r wh ...

  5. python3爬虫:利用urllib与有道翻译获得翻译结果

    在实现这一功能时遇到了一些困难,由于按照<零基础入门python>中的代码无法实现翻译,会爆出“您的请求来源非法,商业用途使用请关注有道翻译API官方网站“有道智云”: http://ai ...

  6. 跨域带cookie失效的解决方案

    在webpack的tableproxy那儿配置完跨域以后,想给cookie添加domain以便请求的时候带上cookie domain为localhost,cookie不会失效,但是一但改成baidu ...

  7. HBase完全分布式集群搭建

    HBase完全分布式集群搭建 hbase和hadoop一样也分为单机版,伪分布式版和完全分布式集群版,此文介绍如何搭建完全分布式集群环境搭建.hbase依赖于hadoop环境,搭建habase之前首先 ...

  8. Windows XP系列全下载(均为MSDN原版)

    正版windows xp sp3 下载大全(附:正版密钥) 微软MSDN Windows XP Professional下载 Windows XP Professional 简体中文 (最原始版本,无 ...

  9. hexo博客的学习笔记

    这篇文章主要的作用是作为 .md文件打开,内部的格式为一个初学者对hexo以及markdown语法运用的笔记 1.Hexo的写文格式 最开始为文章的属性部分,以三横杠-开始,-结束.里面记录了文章的标 ...

  10. 初窥Android AudioFlinger

    Android  AudioFlinger 是Android音频系统的两大服务之一,另一个服务是AudioPolicyService,这两大服务都在系统启动时有MediaSever加载,加载的代码位于 ...