通过注解(特性)的方式进行对象的注册与注入,方便,灵活!

  • 本篇主要讲如何去实现,下一篇主要讲如何把它集成到mvc和api环境里,实现自动的注入!

    spring ioc工作的过程大致为,统一的注册组件,拦截当前请求,统一的注入当前请求所需要的组件,事实上,说到这事,.net也完全可以实现这个功能和工作方式,下来大叔来实现一下

  1. 定义组件注册特性
  2. 定义组件生命周期
  3. 定义组件注入特性
  4. 定义Ioc工厂
  5. 使用灵活方便
  6. 将注入功能集成到mvc的拦截器里

定义组件注册特性

定义在类身上

    /// <summary>/// 注册组件特性./// </summary>[AttributeUsage(AttributeTargets.Class)]public class ComponentAttribute : Attribute{public LifeCycle LifeCycle { get; set; } = LifeCycle.CurrentScope;public String Named { get; set; }}

定义组件生命周期

    /// <summary>/// 组件生命周期/// </summary>public enum LifeCycle{CurrentScope,CurrentRequest,Global,}

定义组件注入特性

定义在字段上

    /// <summary>/// 注入一对象./// </summary>[AttributeUsage(AttributeTargets.Field)]public class InjectionAttribute : Attribute{public string Named{get;set;}}

定义Ioc工厂

    /// <summary>/// DI工厂./// </summary>public class DIFactory{static IContainer container;/// <summary>/// 手动注入./// </summary>/// <returns>The resolve.</returns>/// <typeparam name="T">The 1st type parameter.</typeparam>public static T Resolve<T>(){if (container == null)throw new ArgumentException("please run DIFactory.Init().");return container.Resolve<T>();}/// <summary>/// 手动注入./// </summary>/// <returns>The by named.</returns>/// <param name="named">Named.</param>/// <typeparam name="T">The 1st type parameter.</typeparam>public static T ResolveByNamed<T>(string named){if (container == null)throw new ArgumentException("please run DIFactory.Init().");return container.ResolveNamed<T>(named);}/// <summary>/// 把对象里的Inject特性的对象注入./// web环境下,应该使用filter拦截器将当前控制器传传InjectFromObject去注入它./// </summary>/// <param name="obj">Object.</param>public static void InjectFromObject(object obj){if (obj.GetType().IsClass && obj.GetType() != typeof(string))foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)){if (field.GetCustomAttributes(false).Select(i => i.GetType()).Contains(typeof(InjectionAttribute))){InjectionAttribute inject = (InjectionAttribute)field.GetCustomAttributes(false).FirstOrDefault(i => i.GetType() == typeof(InjectionAttribute));if (inject != null && !String.IsNullOrWhiteSpace(inject.Named)){field.SetValue(obj, container.ResolveNamed(inject.Named, field.FieldType));}else{field.SetValue(obj, container.Resolve(field.FieldType));}//递归处理它的内部字段InjectFromObject(field.GetValue(obj));}}}/// <summary>/// 初始化./// </summary>public static void Init(){var builder = new ContainerBuilder();var arr = AppDomain.CurrentDomain.GetAssemblies().Where(x => !x.FullName.StartsWith("Dapper")&& !x.FullName.StartsWith("System")&& !x.FullName.StartsWith("AspNet")&& !x.FullName.StartsWith("Microsoft")).SelectMany(x => x.DefinedTypes).Where(i => i.IsPublic && i.IsClass).ToList();foreach (var type in arr){try{if (type.GetCustomAttributes(false).Select(i => i.GetType()).Contains(typeof(ComponentAttribute))){ComponentAttribute componentAttribute = (ComponentAttribute)type.GetCustomAttributes(false).FirstOrDefault(o => o.GetType() == typeof(ComponentAttribute));if (type.GetInterfaces() != null && type.GetInterfaces().Any()){type.GetInterfaces().ToList().ForEach(o =>{registor(builder, type, o, componentAttribute);});}else{registor(builder, type, type, componentAttribute);}}}catch (Exception){throw new Exception($"Lind.DI init {type.Name} error.");}}container = builder.Build();}/// <summary>/// 注册组件./// </summary>/// <param name="builder">Builder.</param>/// <param name="typeImpl">Type impl.</param>/// <param name="type">Type.</param>/// <param name="componentAttribute">Component attribute.</param>static void registor(ContainerBuilder builder, Type typeImpl, Type type, ComponentAttribute componentAttribute){if (componentAttribute.LifeCycle == LifeCycle.Global){if (componentAttribute.Named != null)builder.RegisterType(typeImpl).Named(componentAttribute.Named, type).SingleInstance();elsebuilder.RegisterType(typeImpl).As(type).SingleInstance();}else if (componentAttribute.LifeCycle == LifeCycle.CurrentScope){if (componentAttribute.Named != null)builder.RegisterType(typeImpl).Named(componentAttribute.Named, type).InstancePerLifetimeScope();elsebuilder.RegisterType(typeImpl).As(type).InstancePerLifetimeScope();}else{if (componentAttribute.Named != null)builder.RegisterType(typeImpl).Named(componentAttribute.Named, type).InstancePerRequest();elsebuilder.RegisterType(typeImpl).As(type).InstancePerRequest();}}}

使用灵活方便

支持对象与对象之间的依赖

   [Component(Named="RunPeople")]public class RunPeople : IRun{public void Do(){System.Console.WriteLine("人类跑起来!");}}[Component]public class Fly{[Injection(Named="RunPeople")]Run run;public void step1(){run.Do();System.Console.WriteLine("飞行第一步!");}}

使用方式,程序入口先初始化DIFactory.Init();

       [Injection]Fly flyObj;void print(){DIFactory.Init();DIFactory.InjectFromObject(this);flyObj.step1();}static void Main(string[] args){DIFactory.Init();System.Console.WriteLine("Hello World!");new Program().print();}

结果

Hello World!
人类跑起来!
飞行第一步!

转载于:https://www.cnblogs.com/lori/p/10696640.html

设计一下类似SpringIoC的注入工具~Lind.DI相关推荐

  1. SQL 注入工具集合

    众所周知,SQL注入攻击是最为常见的Web应用程序攻击技术.同时SQL注入攻击所带来的安全破坏也是不可弥补的.以下罗列的10款SQL注入工具可帮助管理员及时检测存在的漏洞. BSQL Hacker B ...

  2. php 写一个大富翁游戏,C++大富翁代码 现在要设计一个类似“大富翁”的游戏:有一条由20个格子组成的 联合开发网 - pudn.com...

    C++大富翁代码 所属分类:Windows编程 开发工具:C/C++ 文件大小:349KB 下载次数:6 上传日期:2018-05-15 21:11:38 上 传 者:红黑二叉树 说明:  现在要设计 ...

  3. mysql sql注入工具_基础篇——SQL注入(工具注入)

    注入工具 上一篇介绍了SQL注入漏洞以及一些手工注入方法,本篇介绍一下注入工具 1.sqlmap sqlmap属于比较经典的一个注入工具,功能强大,还自带一些绕过参数 使用方法: sqlmap.py ...

  4. WEB网页设计前端(前台)开发的常用工具推荐

    WEB网页设计前端(前台)开发的常用工具推荐 最近我在搞网页设计,包括网站建设的前台界面设计和JS代码的编写,弄一个JS的时候把我给郁闷了,在寻找JS如何通过子节点操作父节点的时候找到了以下免费的网站 ...

  5. 小啊呜产品读书笔记001:《邱岳的产品手记-02》 开篇词 产品经理的世界没有对错 01讲 验证码是个好设计吗 02讲 产品经理工具指南 03讲 产品案例分析·Trigraphy的设计哲学

    小啊呜产品读书笔记001:<邱岳的产品手记-02> 开篇词 产品经理的世界没有对错 & 01讲 验证码是个好设计吗 & 02讲 产品经理工具指南 & 03讲 产品案 ...

  6. Wifitap是一个WiFi注入工具集常用命令集合大学霸IT达人

    Wifitap是一个WiFi注入工具集常用命令集合大学霸IT达人 该工具集允许任何应用程序都可以发送和接收IP数据包,使用802.11流量捕获和注入,并通过WiFi网络简单配置接口wj0.Wifita ...

  7. 多协议注入工具t50

    多协议注入工具t50 t50是Kali Linux自带的一款网络数据包注入工具.该工具支持15种协议,不仅涵盖常规协议(ICMP.TCP.UDP),还涵盖基础协议和路由协议(GRE.IPSec.RSV ...

  8. 命令注入工具Commix

    命令注入工具Commix 命令注入(Command Injection)攻击是针对Web应用的一种攻击方式.很多Web应用会读取用户提交的数据,然后传递到系统Shell,执行特定的操作,如为用户创建单 ...

  9. 网络数据注入工具HexInject

    网络数据注入工具HexInject 对于Kali Linux提供的工具HexInject来说,数据注入才是其最重要的功能.它可以直接向网络注入渗透人员构造的数据包,也可以篡改网络传输的数据.为了避免修 ...

最新文章

  1. go语言和java比_去过大场面试后,java程序员有没有必要转学Go语言?
  2. 什么是javax.ws.rs.core.context? [ 第1部分 ]
  3. 我的nginx iis 负载均衡学习(环境搭建)
  4. jcr多久更新一次_拼多多商品价格竞争力星级有什么用?多久更新一次?
  5. js做四则运算时,精度丢失问题及解决方法
  6. C#通过XElement写入XML文件
  7. fill()函数和fill_n()函数
  8. c语言二进制转换方式,c语言二进制怎么转换十进制
  9. 21天学会Java之(Java SE第十二篇):多线程、Lambda表达式
  10. win10输入法突然变繁体解决办法
  11. 号外!号外!豪车出租啦!
  12. Git学习-Git时光机之版本回退(二)
  13. Windows如何打开命令模式
  14. Vue中使用百度地图做路径分析并根据起终点坐标模拟道路里程桩
  15. webshell一句话木马大全
  16. 分子对接教程 | (4) 蛋白受体文件的预处理
  17. TextView显示Gif图片实现图文混排
  18. MapABC地图使用
  19. 暗黑起源服务器维护,暗黑起源官方网站
  20. html基础标签-1-pre预格式标签

热门文章

  1. 计算机网络基础知识总结及思维导图(四)网络层
  2. 计算机网络军训口号,军训口号霸气口号(精选60句)
  3. 顶级免费空间hostinger搭建个人网…
  4. QR code(二维码)
  5. 《解忧杂货店》-东野圭吾
  6. 订阅者java_发布者订阅者模式之JAVA实现
  7. KB/s和Kbps是完全不同的概念
  8. 搭建MineCraft私服
  9. 2-15 微信小程序array数据类型(附带方法解析)
  10. C++ 10 翁恺> 继承