自制简单实用IoC
IoC是个好东西,但是为了这个功能而使用类似 Castle 这种大型框架的话,感觉还是不大好
代码是之前写的,一直没详细搞,今天整理了一下,感觉挺实用的.
IoC定义接口:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace System
{
/// <summary>
/// 一个接口,支持IoC定义
/// </summary>
public interface IIoCDefine
{
/// <summary>
/// 定义类型
/// </summary>
/// <param name="type"></param>
/// <param name="implType"></param>
void Define(Type type, Type implType);
/// <summary>
/// 定义类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Impl"></typeparam>
void Define<T, Impl>() where Impl : T;
}
}
IoC解析接口:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace System
{
/// <summary>
/// 一个接口,支持IoC解析
/// </summary>
public interface IIoCResolve
{ /// <summary>
/// 解析类型
/// </summary>
/// <param name="type"></param>
object Resolve(Type type);
/// <summary>
/// 解析类型
/// </summary>
/// <typeparam name="T"></typeparam>
T Resolve<T>();
}
}
具体实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace System
{
/// <summary>
/// 支持定义解析
/// </summary>
internal class ResolveBase : IIoCResolve, IIoCDefine
{ ICache<Type, Type> _typeMaps = CacheFactory.CreateCache<Type, Type>(); ICache<string, Type> _genericTypeMaps = CacheFactory.CreateCache<string, Type>(); /// <summary>
/// 定义类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Impl"></typeparam>
public void Define<T, Impl>() where Impl : T
{
Define(typeof(T), typeof(Impl));
} /// <summary>
/// 定义类型
/// </summary>
/// <param name="type"></param>
/// <param name="implType"></param>
public void Define(Type type, Type implType)
{
if (type == null)
{
throw Error.ArgumentNullException("type");
}
if (implType == null)
{
throw Error.ArgumentNullException("implType");
} if (implType.IsInterface || implType.IsAbstract)
{
throw Error.ArgumentException("不能是抽象类型或接口", "implType");
} if (!type.IsGenericTypeDefinition == implType.IsGenericTypeDefinition)
{
throw Error.ArgumentException("泛型不能与非泛型互转", "implType");
} if (!implType.IsGenericTypeDefinition && !type.IsAssignableFrom(implType) && !type.GetTypeInfo().IsAssignableFrom(implType))
{
throw Error.ArgumentException("不是子类", "implType");
} _typeMaps[type] = implType; if (type.IsGenericType)
{
_genericTypeMaps[GetGenericTypeDefinitionKey(type)] = implType;
} } string GetGenericTypeDefinitionKey(Type type)
{ // var temp = _typeMaps.Keys.FirstOrDefault(o => o.IsGenericType && o.Name == type.Name && o.Namespace == o.Namespace && o.Module.Equals(type.Module));
//return type.Name + "_" + type.Namespace + "_" + type.Module.Name; return type.FullName + "_" + type.Module.Name;
} /// <summary>
/// 得到类型实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Resolve<T>()
{
Type type = typeof(T); return (T)Resolve(type);
} /// <summary>
/// 得到类型实例
/// </summary>
/// <returns></returns>
public object Resolve(Type type)
{ var instanceType = GetInstanceType(type); //if (instanceType.IsAbstract || instanceType.IsInterface)
//{
// throw Error.ArgumentException("解析失败 : 不能是接口或抽象类");
//} return ActivatorCache.CreateInstance(instanceType); // return Activator.CreateInstance(instanceType);
} /// <summary>
/// 得到解析类型
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
Type GetInstanceType(Type type)
{
if (type == null)
{
throw Error.ArgumentNullException("type");
}
Type instanceType; if (!type.IsGenericType)
{
//如果非泛型,直接拿缓存
instanceType = _typeMaps[type];
if (instanceType == null)
{
throw Error.ArgumentException("解析失败 : 未定义解析类型");
}
return instanceType;
} //是泛型
instanceType = _genericTypeMaps[GetGenericTypeDefinitionKey(type)]; if (instanceType == null)
{
if (type.IsGenericTypeDefinition)
{
throw Error.ArgumentException("解析失败 : 未定义解析类型");
}
//找不到具体泛型类型
//从泛型定义中找
var genericType = type.GetGenericTypeDefinition();
instanceType = _genericTypeMaps[GetGenericTypeDefinitionKey(genericType)];
if (instanceType == null)
{
throw Error.ArgumentException("解析失败 : 未定义解析类型");
}
instanceType = instanceType.MakeGenericType(type.GenericTypeArguments);
} if (type.IsGenericTypeDefinition)
{
//指定泛型参数类型
var gType = instanceType.MakeGenericType(type.GenericTypeArguments);
instanceType = gType;
} return instanceType;
} //bool Equals(Type[] types1, Type[] types2)
//{
// if (types1 == null || types2 == null)
// {
// return false;
// }
// if (types1.Length != types2.Length)
// {
// return false;
// } // int length = types1.Length; // for (int i = 0; i < length; i++)
// {
// var type1 = types1[i];
// var type2 = types2[i]; // if (!types1.Equals(type2) && !(type1.IsAssignableFrom(type2) || type2.IsAssignableFrom(type1)))
// {
// return false;
// } // } // return true; //} public object Resolve(Type type, params object[] values)
{
var instanceType = GetInstanceType(type); if (instanceType.IsAbstract || instanceType.IsInterface)
{
throw Error.ArgumentException("解析失败 : 不能是接口或抽象类");
} var types = values.Select(o => o.GetType()).ToArray(); return ActivatorCache.CreateInstance(instanceType, values); // return Activator.CreateInstance(instanceType, values);
} public T Resolve<T>(params object[] values)
{ return (T)Resolve(typeof(T), values);
}
}
}
给个入口:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace System
{ /// <summary>
/// IoC入口对象
/// </summary>
public sealed class IoCManager : IIoCResolve, IIoCDefine
{
IoCManager()
{
var resolve = new ResolveBase();
_resolve = resolve;
_define = resolve;
} public static readonly IoCManager Instance = new IoCManager(); IIoCResolve _resolve; IIoCDefine _define; /// <summary>
/// 定义类型
/// </summary>
/// <param name="type"></param>
/// <param name="implType"></param>
public void Define(Type type, Type implType)
{
_define.Define(type, implType);
} /// <summary>
/// 定义类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Impl"></typeparam>
public void Define<T, Impl>() where Impl : T
{
_define.Define<T, Impl>();
} /// <summary>
/// 解析类型
/// </summary>
/// <param name="type"></param>
/// <param name="implType"></param>
public object Resolve(Type type)
{
return _resolve.Resolve(type);
} /// <summary>
/// 解析类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Impl"></typeparam>
public T Resolve<T>()
{
return _resolve.Resolve<T>();
} }
}
到这里就大功告成了!!!
测试:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Dai.CommonLib.Tests.Models
{
public interface TestInterface
{
} public interface TestInterface<T>:TestInterface
{
} class TestClass : TestInterface
{ } class TestClass<T> : TestInterface<T>
{ } class TestClass1<T> : TestClass<T>
{ } }
[TestMethod]
public void TestMethod2()
{ IoCManager.Instance.Define(typeof(TestInterface), typeof(TestClass<decimal>)); IoCManager.Instance.Define(typeof(TestInterface<>), typeof(TestClass<>)); IoCManager.Instance.Define(typeof(TestInterface<string>), typeof(TestClass1<string>)); var model = IoCManager.Instance.Resolve<TestInterface>(); var model1 = IoCManager.Instance.Resolve<TestInterface<int>>(); var model2 = IoCManager.Instance.Resolve<TestInterface<string>>(); Assert.IsTrue(model is TestClass<decimal>); Assert.IsTrue(model1 is TestClass<int>); Assert.IsTrue(model2 is TestClass1<string>); IoCManager.Instance.Define(typeof(TestInterface), typeof(TestClass)); var model3 = IoCManager.Instance.Resolve<TestInterface>(); Assert.IsTrue(model3 is TestClass);
}
优点: 支持泛型,如果指定了具体的泛型类型,那优先解析具体类型,否则从泛型类型定义中替换具体泛型类型参数,如上面的代码的 TestClass和TestClass1类型
下次写个Aop Inject 静态编织注入的文章
自制简单实用IoC的更多相关文章
- jQuery的几种简单实用效果
许久未分享博客,或许已生疏. 闲来无事, 分享几个jQuery简单实用的效果案例 不喜勿喷... 1.页面常用的返回顶部 <!DOCTYPE html> <html lang=&qu ...
- IoC原理-使用反射/Emit来实现一个最简单的IoC容器
从Unity到Spring.Net,到Ninject,几年来陆陆续续用过几个IoC框架.虽然会用,但也没有一直仔细的研究过IoC实现的过程.最近花了点时间,下了Ninject的源码,研究了一番,颇有收 ...
- 【最简单IOC容器实现】实现一个最简单的IOC容器
前面DebugLZQ的两篇博文: 浅谈IOC--说清楚IOC是什么 IoC Container Benchmark - Performance comparison 在浅谈IOC--说清楚IOC是什么 ...
- 经验分享:10个简单实用的 jQuery 代码片段
尽管各种 JavaScirpt 框架和库层出不穷,jQuery 仍然是 Web 前端开发中最常用的工具库.今天,向大家分享我觉得在网站开发中10个简单实用的 jQuery 代码片段. 您可能感兴趣的相 ...
- 简单实用的PHP防注入类实例
这篇文章主要介绍了简单实用的PHP防注入类实例,以两个简单的防注入类为例介绍了PHP防注入的原理与技巧,对网站安全建设来说非常具有实用价值,需要的朋友可以参考下 本文实例讲述了简单实用的PHP防注 ...
- php简单实用的操作文件工具类(创建、移动、复制、删除)
php简单实用好用的文件及文件夹复制函数和工具类(创建.移动.复制.删除) function recurse_copy($src,$dst) { // 原目录,复制到的目录 $dir = opend ...
- php 简单说明IoC (php 实例+注释)
简单说明IoC <?php //Ioc ———— 设计方式 //控制反转 Inversion of Control //依赖关系的转移 //依赖抽象而非实践 //用于解决高层应用依赖 底层组件, ...
- 基于Bootstrap简单实用的tags标签插件
http://www.htmleaf.com/jQuery/ jQuery之家 自由分享jQuery.html5和css3的插件库 基于Bootstrap简单实用的tags标签插件
- C#_简单实用的翻页
简单实用的生成翻页HTML辅助类 C# using System.Text; namespace ClassLibrary { /// <summary> /// /// </sum ...
随机推荐
- 关于提高webview里下载apk安装包成功率的研究
移动互联网发展到当下,各种领域出现了一些大的app平台,这些app共同的特点就是拥有大量忠实活跃用户, 要知道,有用户就有money啊~ 于是乎其他不太知名的平台,开始在他们上面疯狂投放广告,做活动推 ...
- C语言结构体-struct
知识点: 1)结构体的定义. 2)结构体的sizeof. 3) 结构体的指针. 1) 结构体的定义: 在逻辑上有一定关联的多个数据类型做为一整体进行操作的数据结构,它的关键字是struct.下面我将 ...
- centos 6.5 X64 安装 mongodb 2.6.1 (笔记 实测)
环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G) 系统版本:Centos-6.5-x86_64 *** Centos编译安装mongodb 2.6 系统最好是64位的,才 ...
- Python黑客编程2 入门demo--zip暴力破解
Python黑客编程2 入门demo--zip暴力破解 上一篇文章,我们在Kali Linux中搭建了基本的Python开发环境,本篇文章为了拉近Python和大家的距离,我们写一个暴力破解zip包密 ...
- 【读书笔记】-- JavaScript数组
数组是一段线性分配的内存,它通过整数计算偏移并访问其中的元素.大多数的语言都会要求一个数组的元素是相同类型,但JavaScript数组可以包含任意类型. var misc = ['string', n ...
- 赴美工作常识(Part 5 - 绿卡优先级)
这个系列的第一篇<赴美工作常识(Part 1 - 签证)>是三年前写的,过了这么久这个系列终于要继续下去了.接下来当然时讨论绿卡的事情了.跟讨论签证一样,这里必须要有免责声名.因为我不是移 ...
- 值得使用的Spring Boot
2013年12月12日,Spring发布了4.0版本.这个本来只是作为Java平台上的控制反转容器的库,经过将近10年的发展已经成为了一个巨无霸产品.不过其依靠良好的分层设计,每个功能模块都能保持较好 ...
- HttpContext.Current:异步模式下的疑似陷阱之源
最近园子里首页有好几篇文章都是讲异步编程的,尤其是几篇讲博客园自身的异步化建设的文章,看了以后很有收获. 闲暇之余再重新查查资料温故知新学习一遍,重新认识了SynchronizationContext ...
- querySelector和querySelectorAll
jQuery被开发者如此的青睐和它强大的选择器有很大关系,比起笨重的document.getElementById.document.getElementByName… ,查找元素很方便,其实W3C中 ...
- 诡异的 未处理的IOErrorEvent 2035
今天游戏发布上线之后,总是随机的出现卡死. 换了个safari之后,看到抛了 IOErrorEvent. 问题是,我所有的Loader都加入了contentLoaderInfo监听.而抛出来的又没有堆 ...