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

  • 本篇主要讲如何去实现,下一篇主要讲如何把它集成到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();
else
builder.RegisterType(typeImpl).As(type).SingleInstance();
}
else if (componentAttribute.LifeCycle == LifeCycle.CurrentScope)
{
if (componentAttribute.Named != null)
builder.RegisterType(typeImpl).Named(componentAttribute.Named, type).InstancePerLifetimeScope();
else
builder.RegisterType(typeImpl).As(type).InstancePerLifetimeScope();
}
else
{
if (componentAttribute.Named != null)
builder.RegisterType(typeImpl).Named(componentAttribute.Named, type).InstancePerRequest();
else
builder.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!
人类跑起来!
飞行第一步!

设计一下类似SpringIoC的注入工具~Lind.DI的更多相关文章

  1. 十大关系数据库SQL注入工具一览

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

  2. 10个SQL注入工具(转载)

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

  3. 10 个 SQL 注入工具

    BSQL Hacker BSQL Hacker是由Portcullis实验室开发的,BSQL Hacker 是一个SQL自动注入工具(支持SQL盲注),其设计的目的是希望能对任何的数据库进行SQL溢出 ...

  4. So注入工具TsoInject开发文档

    So注入工具TsoInject开发文档 导语: 作为一个软件安全从业者而言,我们需要对某个App的关键函数就行Hook, 对于android而言,Smali层我们使用Xposed Hook框架,So层 ...

  5. oracle union 注入工具

    '***********************************************************************************************'ora ...

  6. 详解强大的SQL注入工具——SQLMAP

    1. 前言  Windows下的注入工具好的又贵,免费的啊D.明小子等又不好用,我们根本没必要花 时间去找什么破解的havij.pangolin什么的,特别是破解的工具很可能被绑了木马.其实 Linu ...

  7. 记一次SQL联合查询注入工具的编写

    这是一个ASP网站的简单SQL注入检测和利用的工具,主要的功能是简单的检测出SQL注入漏洞,可以使用该id存在的SQL注入来获取数据库中的网站管理员的表名和字段名,猜解数据库中该表的字段数,最后通过联 ...

  8. sql注入工具:sqlmap命令

    sqlmap是一款专业的sql注入工具, 让你告别人工注入, 程序高效自动注入 前提是你有找到注入点 , 工具的官方网站:http://sqlmap.org/ kali系统默认安装sqlmap, 不需 ...

  9. 如何编写一个SQL注入工具

    0x01  前言 一直在思考如何编写一个自动化注入工具,这款工具不用太复杂,但是可以用最简单.最直接的方式来获取数据库信息,根据自定义构造的payload来绕过防护,这样子就可以. 0x02 SQL注 ...

随机推荐

  1. php 阿里云短信服务及阿里大鱼实现短信验证码的发送

    一:使用阿里云的短信服务 ① 申请短信签名 ②申请短信模板 ③创建Access Key,获取AccessKeyId 与 AccessKeySecret.(为了安全起见,这里建议使用子用户的Access ...

  2. 在C++98基础上学习C++11新特性

    自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ...

  3. .NET开发微信小程序-接收微信支付回调数据

    获取微信支付传回来的数据 1.MVC控制器 /// <summary> /// 付款返回的数据 /// </summary> /// <returns></r ...

  4. MySQL中查询时"Lost connection to MySQL server during query"报错的解决方案

    一.问题描述: mysql数据库查询时,遇到下面的报错信息: 二.原因分析: dw_user 表数据量比较大,直接查询速度慢,容易"卡死",导致数据库自动连接超时.... 三.解决 ...

  5. Linux时间子系统之(十四):tick broadcast framework

    专题文档汇总目录 Notes:BroadcastTick作为cpuidle的waker,硬件基础.BroadcastTick嵌入在当前系统Tick框架中.BroadcastTick设备初始化:周期性T ...

  6. .NET Orm 性能测试

    .NET Orm 性能测试 简介 OrmBenchmark 这个项目主要是为了测试主要的Orm对于 SqlServer 数据库的查询并将数据转换成所需 POCO 对象的耗时情况(好吧,实际上不完全or ...

  7. 玩转spring MVC(八)----spring MVC整合json

    这篇文章在前边项目的基础上来整合json,最新项目资料见:http://download.csdn.net/detail/u012116457/8436187 首先需要的jar包:jackson-co ...

  8. 在echarts里在geojson绘制的地图上展示散点图(气泡)、线集。

    先来要实现的效果图: 下方图1是官网的案例:http://www.echartsjs.com/gallery/editor.html?c=scatter-map 下图2是展示气泡类型为pin的效果: ...

  9. java基础学习周计划之3--每周一练

    每周一练第一周 一. 关键代码:1.斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...数列第一项和第二项是1, 从第三项开始, ...

  10. 使用Eclipse远程调试

    在一般的开发中,有事因为项目需要,测试环境是在Linux下,这是如果出现异常或者bug,调试起来都是很费劲的,如果你还在为这个头疼,那就好好看接下来的总结 1,启动改程序时,不论是脚本启动,还是tom ...