实现一个简易的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容器实现的更多相关文章

  1. 自己实现IOC容器,java代码实现简易版IOC容器,IOC容器实现的步骤分解

    一.需求 实现一个简易的IOC容器,管理Bean,从IOC容器的BeanFactory中获取实例,从而取代自己new实例的做法. 二.实现步骤分析 三.具体代码实现 自定义注解类 MyComponen ...

  2. DI 原理解析 并实现一个简易版 DI 容器

    本文基于自身理解进行输出,目的在于交流学习,如有不对,还望各位看官指出. DI DI-Dependency Injection,即"依赖注入":对象之间依赖关系由容器在运行期决定, ...

  3. 2.自己搭建的一个简易的ioc容器

    1.persondao类namespace MyselfIoC{    public class PersonDao    {        public override string ToStri ...

  4. DOTNET CORE源码分析之IOC容器结果获取内容补充

    补充一下ServiceProvider的内容 可能上一篇文章DOTNET CORE源码分析之IServiceProvider.ServiceProvider.IServiceProviderEngin ...

  5. 从0开始搭建一个IoC容器(C#版)

    网址:https://blog.csdn.net/wangyahua1234/article/details/100619695 目录 1. IoC简介 2. Tiny版IoC的功能 3. Tiny版 ...

  6. ASP.NET Core中使用IOC三部曲(一.使用ASP.NET Core自带的IOC容器)

    前言 本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期. 这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度. 目录 ...

  7. ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)

    前言 本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期. 这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度. 目录 ...

  8. Ioc容器与laravel服务容器初探

    一.Ioc容器 某天,小J心血来潮,决定建造一艘星舰,这艘星舰要搭载"与众不同最时尚,开火肯定棒"的电磁炮.于是他写了一个星舰类: class ElectromagneticGun ...

  9. Spring.net(二)----初探IOC容器

    我在上一篇关于Spring.net的文章“Spring.NET框架简介及模块说明 ”中很详细的介绍了,本文就不旧话从提.我门就直奔主题吧. 1.首先了解两个接口.  IObjectFactory接口和 ...

  10. IOC容器特性注入第一篇:程序集反射查找

    学习kooboo的框架发现它的注入容器方法比较特别,同样是利用MVC的注入点,但它是查找网站下面bin所有的DLL利用反射查找特性找到对应的服务注入到容器. 这样的好处很简单:完全可以不用关心IOC容 ...

随机推荐

  1. JS 转盘抽奖效果

    阅读原文,微信扫描二维码, 手机关注公共号酒酒酒酒,搜索 JS 转盘抽奖效果 效果图 前置条件: 开发环境:windows 开发框架:js 编辑器:HbuilderX 正文开始 <!DOCTYP ...

  2. Go语言单元测试的执行

    Go 语言推荐测试文件和源代码文件放在同一目录下,测试文件以 _test.go 结尾.比如,当前 package 有 calc.go 一个文件,我们想测试 calc.go 中的 Add 和 Mul 函 ...

  3. 一些很好用的SVN功能

    1.checkout 1.1 只checkout部分目录和文件 目的:有时候项目的文件很多,但是只会关心其中的某几个文件,就可以只checkout这几个文件,可以缩短checkout时间且减少其他文件 ...

  4. Antlr4 语法解析生成器(上)

    简介 Spark SQL.Presto --> Antlr4 SQL 解析器 Flink SQL --> Apache Calcite(通过JavaCC 实现) Spark SQL如何进行 ...

  5. 3.2 Linux文件系统到底有什么用处?

    Linux 上常见的文件系统是EXT3或EXT4,但这篇文章并不准备一上来就直接讲它们,而希望结合Linux操作系统并从文件系统建立的基础--硬盘开始,一步步认识Linux的文件系统. 1.机械硬盘的 ...

  6. 13-2 c++拷贝控制和资源管理

    目录 13.2.1 行为像值的类 类拷贝赋值运算符的编写 13.2.2 定义行为像指针的类 引用计数 定义一个使用引用计数的类 为了定义这些成员,我们首先必须确定此类型对象的拷贝语义.一般来说,有两种 ...

  7. Mysql数据库笔记整理

    数据库-理论基础 1.什么是数据库? 数据:描述事物的符号记录,可以是数字.文字.图形.图像.声音.语言等,数据有多种形式,它们都可以经过数字化后存入计算机. 数据库:存储数据的仓库,是长期存放在计算 ...

  8. VMware使用Ubuntu20.04时发生屏幕闪烁

    问题:VMware使用Ubuntu20.04时发生屏幕闪烁 分析:这是由于虚拟机里面的显示器不支持3D加速问题导致的 解决方法:关闭虚拟机 → 左上角菜单 → 虚拟机 → 设置 → 显示器 → 取消勾 ...

  9. Impala学习--Impala前端代码分析,Impala后端代码分析

    Impala前端代码分析 Table of Contents 1 概述 2 语法分析和ParseNode 3 Analyzer 4 生成执行计划和Planner 5 Catalog 1 概述 前端代码 ...

  10. Linux常用系统性能监控工具

    top 首先关于top命令,我想大家应该都挺熟悉的了. Linux系统下的top命令有点类似于Windows系统里的任务管理器,能够实时动态地给出系统中各个进程的资源占用状况,是Linux下比较常用的 ...