.net core反射练习-简易版IOC容器实现
Posted exxxxia
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.net core反射练习-简易版IOC容器实现相关的知识,希望对你有一定的参考价值。
实现一个简易的IOC容器
先说一下简单思路,参考ServiceCollection,需要一个注册方法跟获取实例方法,同时支持构造函数注入。那么只需要一个地方存储注册接口跟该接口的继承类,以及根据类的构造函数去实例化一个对象出来。
创建一个.net core控制台程序,新建一个Container类。
创建一个静态字典存储类以及对应的type,这就是存储注册接口的地方
static Dictionary<string, Type> typeDic = new Dictionary<string, Type>();
然后就是实例化对象方法
/// <summary> /// 根据类型实例化对象 /// </summary> /// <param name="type"></param> /// <returns></returns> public T GetService<T>() var type = typeof(T); var targetType = typeDic[type.FullName]; return (T)Activator.CreateInstance(targetType);
很简单的一个方法,也有很明显的缺陷,不过现在已经可以根据注册的接口来实例化一个类。
最明显的一个问题是,没有根据构造函数来实例化类,下面来进行改进:
/// <summary> /// 根据类型实例化对象 /// </summary> /// <param name="type"></param> /// <returns></returns> public object CreateInstance(Type type) object result = new object(); var targetType = typeDic[type.FullName]; var ctor = targetType.GetConstructors().OrderByDescending(c => c.GetParameters().Length).FirstOrDefault(); var paraList = new List<object>(); if (ctor != null) foreach (var para in ctor.GetParameters()) var paraType = para.ParameterType; var paraInstance = CreateInstance(paraType); paraList.Add(paraInstance); try result = Activator.CreateInstance(targetType, paraList.ToArray()); catch (Exception ex) Console.WriteLine(ex.Message); return result;
把容器实例化对象的方法独立出来,上面的方法做了两个改进:
- 默认选取最多参数的构造函数,这也是ServiceCollection的策略
- 递归构造函数里面的每个参数,为每个参数都进行实例化
再添加一个方法调用该方法给外部使用
/// <summary> /// 获取实例 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public T GetService<T>() return (T)CreateInstance(typeof(T));
到这里就可以进行测试了,新建一个ISql接口,创建一个查询方法
namespace ISql public interface ISqlHelpr void Query();
分别创建两个类继承ISql
using System; using ISql; namespace MySqlTest public class MySqlHelpr : ISqlHelpr public void Query() Console.WriteLine("使用Mysql查询");
using System; using ISql; namespace MySqlServerTest public class SqlServerHelper : ISqlHelpr public void Query() Console.WriteLine("使用SqlServer查询");
返回控制台,新建一个容器,注册,获取实例,进行测试:
可以看到注册不同的类就实例化了对应的对象实例
下面再创建一个testClass类继承Itest接口,在MySqlHelper类中调用,展示构造函数注入
public interface Itest public void consoleTest(); public class testClass : Itest public void consoleTest() Console.WriteLine("调用consoleTest");
修改MySqlHelpr
public class MySqlHelpr : ISqlHelpr private readonly Itest _testClass; public MySqlHelpr(Itest testClass) _testClass = testClass; public void Query() _testClass.consoleTest(); Console.WriteLine("使用Mysql查询");
回到控制台,注册testClass,就可以看到结果
done
以上是关于.net core反射练习-简易版IOC容器实现的主要内容,如果未能解决你的问题,请参考以下文章
spring学习总结002 --- IOC容器启动源码(简易版)
手写实现自定义简易版Spring (实现IoC 和 AOP)