标签:
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 静态编织注入的文章
标签:
原文地址:http://www.cnblogs.com/pokemon/p/5479162.html