首页 > 其他分享 >.NET通过反射实现依赖注入

.NET通过反射实现依赖注入

时间:2023-07-12 15:35:37浏览次数:28  
标签:反射 依赖 string object 实例 NET type public

设计通过反射实现依赖注入


    class Program
    {
        //获取到当前程序的程序集,并且获取元数据信息
        public  static Assembly assembly = Assembly.GetCallingAssembly();
        static void Main(string[] args)
        {
            var types = assembly.GetTypes();
            var DI = new DependencyInjectionTest();
            Type type = typeof(MyClass);
            var res = DI.StartASPNETCORE(type, "Action", types, "Eson", "Liu");
            Console.WriteLine(res);

        }

上面代码的作用是,获取到当前程序的程序集,并且获取元数据信息。
这是反射第一步。
1.1 构建依赖注入过程

      /// <summary>
    /// 接口
    /// </summary>
    public interface ITest
    {
        string Add(string a, string b);
    }
    /// <summary>
    /// 实现
    /// </summary>
    public class Test : ITest
    {
        public string Add(string a, string b)
        {
            Console.WriteLine("Add方法被调用执行");
            return a + b;
        }
    }

使用依赖注入

public class MyClass
  {
      private ITest _test;
      public MyClass(ITest test)
      {
          _test = test;
      }
      public string Action(string a, string b)
      {
          Console.WriteLine("Action方法执行");
          return _test.Add(a, b);
      }
  }

1.2 依赖实例化
获取一个类型的构造函数中,所有参数信息,并且为每一个类型实现自动创建实例.
传入参数:需要进行依赖注入的类型的 Type。
返回数据:构造函数参数的实例对象列表(反射都是object)。

        /// <summary>
        /// 实例化依赖
        /// </summary>
        /// <param name="type">要被实例化依赖注入的类型</param>
        /// <param name="types">当前程序集的元数据类型</param>
        public object[] CreateType(Type type, Type[] types)
        {
            // 这里只使用一个构造函数
            ConstructorInfo? constructor = type.GetConstructors().FirstOrDefault();
            // 获取类型的构造的函数参数
            ParameterInfo[] paramList = constructor.GetParameters();
            // 依赖注入的对象列表
            List<object> objectList = new List<object>();

            foreach (ParameterInfo item in paramList)
            {
                //获取参数类型:item.ParameterType.Name
                //获取程序中,哪个类型实现了 item 的接口
                Type? who = types.FirstOrDefault(x => x.GetInterfaces().Any(z => z.Name == item.ParameterType.Name));
                //实例化
                object? create = Activator.CreateInstance(who);
                if (create != null) objectList.Add(create);
            }
            return objectList.ToArray();
        }

1.3 实例化类型、依赖注入、调用方法
目前来到了依赖注入的最后阶段,实例化一个类型、注入依赖、调用方法。

        /// <summary>
        /// 实现依赖注入、调用方法
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="actionName">方法名称</param>
        /// <param name="paramList">调用方法的参数列表</param>
        /// <returns></returns>
        public object StartASPNETCORE(Type type, string actionName, Type[] types, params object[] paramList)
        {
            // 获取 Action 重载方法 
            // 名字一样,参数个数一致
            MethodInfo? method = type.GetMethods().FirstOrDefault(x => x.Name.ToLower() == actionName.ToLower()
                                                                       && x.GetParameters().Length == paramList.Length);
            // 实例化MyClass

            // 通过 CreateType 方法,拿到已经实例化类型的构造函数的参数对象
            object[]? inject = CreateType(type, types);
            // 注入依赖,实例化对象
            object? example = Activator.CreateInstance(type, inject);
            // 执行方法并且返回执行结果
            object result;
            result = method.Invoke(example, paramList);
            return result;
        }

通过 CreateType 方法,已经拿到实例化类型的构造函数的参数对象了。这里确定调用哪个重载方法的方式,是通过参数的多少,因为这里控制台输入只能获取 string。
流程图

标签:反射,依赖,string,object,实例,NET,type,public
From: https://www.cnblogs.com/EsonLiu/p/17547594.html

相关文章

  • SpringBoot中使用Netty开发WebSocket服务-netty-websocket-spring-boot-starter开源项
    场景SpringBoot+Vue整合WebSocket实现前后端消息推送:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/114392573SpringCloud(若依微服务版为例)集成WebSocket实现前后端的消息推送:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/114480731若依前后......
  • Vue3+.net6.0 六 条件渲染
    v-if,v-else-if,v-else控制元素是否渲染,不满足条件的时候不会有相应元素。<divv-if="type==='A'">A</div><divv-else-if="type==='B'">B</div><divv-else-if="type==='C'">C&l......
  • Microsoft.AspNetCore.Http.Abstractions 2.20 is deprecated
     您想要升级Microsoft.AspNetCore.Http.Abstractions包,您需要注意以下几点:Microsoft.AspNetCore.Http.Abstractions包在ASP.NETCore2.2版本后已经被标记为过时,因为它已经被包含在Microsoft.AspNetCore.App框架引用中12。因此,您不需要单独引用这个包,只需要在项目文件中......
  • Vue3+.net6.0 五 类和样式绑定
    Vue3关于样式的处理跟Vue2是一样的,常用的有以下几种。1.绑定属性html部分:<div:class="{active:isActive}"></div>js部分:data(){return{isActive:true}}当isActive值为true时,div应用这个active样式,反之亦然。 2.对象方式绑定<div:class="cla......
  • 19:vue3 依赖注入
    1、通过Prop逐级透传问题(传统老的方法只能逐级传递) 传统方式代码如下:App.vue1<template>2<h3>祖宗</h3>3<Parent:msg="msg"></Parent>4</template>56<script>7importParentfrom"./components/Parent.vue"......
  • 使用C#编写.NET分析器(三)
    译者注这是在Datadog公司任职的KevinGosse大佬使用C#编写.NET分析器的系列文章之一,在国内只有很少很少的人了解和研究.NET分析器,它常被用于APM(应用性能诊断)、IDE、诊断工具中,比如Datadog的APM,VisualStudio的分析器以及Rider和Reshaper等等。之前只能使用C++编写,自从.NETNative......
  • 一个高性能、低内存文件上传流.Net组件
    推荐一个用于轻松实现文件上传功能的组件。项目简介一个基于.NET平台的开源项目,提供了一个简单易用的API,可以在Web应用程序中快速集成文件上传功能。优化多部分流式文件上传性能:减少25%的CPU使用量、50%内存。项目特点1、简单易用的API: 提供了简单的API,可以轻松地集成......
  • Maven enforcer插件依赖收敛问题
    当项目中引入新的jar包或者升级jar后,重新构建Maven项目时常出现这种报错:Failedtoexecutegoalorg.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M2:enforce(enforce-rules)onprojectxxx-xxxx:SomeEnforcerruleshavefailed. 报错信息  从报错信息看和M......
  • .NET API 001 Convert 类
    Convert类publicstaticclassConvertConvert类是一个静态类,作用是将基本数据类型转换为另一个基本数据类型。继承关系:Object->Convert基本数据类型之间的特定转换存在五种结果,这取决于运行时要转换的基本类型与目标基本类型,具体如下:未转换。试图将一个基本类型转换......
  • 【Netty】「源码解析」(三)设置连接超时:深入分析 ChannelFuture.sync() 的执行过程
    前言本篇博文是《从0到1学习Netty》中源码系列的第三篇博文,主要内容是深入分析连接超时的实现原理,包括了connect方法的源码解析和ChannelFuture.sync()执行过程的解析。,往期系列文章请访问博主的Netty专栏,博文中的所有代码全部收集在博主的GitHub仓库中;介绍在实际应用中,当......