1.创建【特性】用于标注依赖注入

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic; namespace Util.Attributes
{
/// <summary>
/// 标注要运用DI的类 被此属性标注的类 要被注册到依赖注入容器中 并且可以指定类要映射的接口或者类
/// 此属性只能运用于类,并且此属性不能继承
/// </summary>
[AttributeUsage(AttributeTargets.Class,Inherited =false)]
public class UseDIAttribute:Attribute
{
//Targets用于指示 哪些接口或者类 要被 "被属性修饰了的类" 进行依赖注入
public List<Type> TargetTypes=new List<Type>();
public ServiceLifetime lifetime;
public UseDIAttribute(ServiceLifetime argLifetime,params Type[] argTargets)
{
lifetime = argLifetime;
foreach (var argTarget in argTargets)
{
TargetTypes.Add(argTarget);
}
} public List<Type> GetTargetTypes()
{
return TargetTypes;
}
public ServiceLifetime Lifetime
{
get
{
return this.lifetime;
}
}
}
}

2.对程序集中要注入的类进行标记

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using System.Threading.Tasks;
using User.Domain;
using User.Domain.POCOModels;
using Util.Attributes; namespace DDD.Repositories.UserRepositories
{
[UseDI(ServiceLifetime.Scoped,typeof(ILoginRepository))]
public class LoginEFCoreRepository:ILoginRepository
{
private readonly DbContext dbContext;
public LoginEFCoreRepository(DbContext dbContext)
{
this.dbContext = dbContext;
}
}
}

3.为IserviceCollection扩展一个方法  可以实现对程序集进行操作

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Util.Attributes; namespace Util.DIPlugin
{
public static class NetCoreDIModuleRegister
{
/// <summary>
/// 自动注册服务
/// </summary>
/// <param name="services">注册服务的集合(向其中注册)</param>
/// <param name="ImplementationType">要注册的类型</param>
public static void AutoRegisterService(this IServiceCollection services, Type ImplementationType)
{
//获取类型的 UseDIAttribute 属性 对应的对象
UseDIAttribute attr = ImplementationType.GetCustomAttribute(typeof(UseDIAttribute)) as UseDIAttribute;
////获取类实现的所有接口
//Type[] types = ImplementationType.GetInterfaces();
List<Type> types = attr.GetTargetTypes();
var lifetime = attr.Lifetime;
//遍历类实现的每一个接口
foreach (var t in types)
{
//将类注册为接口的实现-----但是存在一个问题,就是担心 如果一个类实现了IDisposible接口 担心这个类变成了这个接口的实现
ServiceDescriptor serviceDescriptor = new ServiceDescriptor(t, ImplementationType, lifetime);
services.Add(serviceDescriptor);
}
}

/// <summary>
/// 根据程序集的名字获取程序集中所有的类型集合
/// </summary>
/// <param name="AssemblyName">程序集名字</param>
/// <returns>类型集合</returns>
public static Type[] GetTypesByAssemblyName(String AssemblyName)
{
Assembly assembly = Assembly.Load(AssemblyName);
return assembly.GetTypes();
} #region 将程序集中的所有符合条件的类型全部注册到 IServiceCollection 中 重载1
/// <summary>
/// 将程序集中的所有符合条件的类型全部注册到 IServiceCollection 中
/// </summary>
/// <param name="services">IServiceCollection</param>
/// <param name="AassemblyName">程序集名字</param>
public static void AutoRegisterServicesFromAssembly(this IServiceCollection services, string AassemblyName)
{
//根据程序集的名字 获取程序集中所有的类型
Type[] types = GetTypesByAssemblyName(AassemblyName);
//过滤上述程序集 首先按照传进来的条件进行过滤 接着要求Type必须是类,而且不能是抽象类
IEnumerable<Type> _types = types.Where(t => t.IsClass && !t.IsAbstract);
foreach (var t in _types)
{
IEnumerable<Attribute> attrs = t.GetCustomAttributes();
//遍历类的所有特性
foreach (var attr in attrs)
{
//如果在其特性中发现特性是 UseDIAttribute 特性 就将这个类注册到DI容器中去
//并跳出当前的循环 开始对下一个类进行循环
if (attr is UseDIAttribute)
{
services.AutoRegisterService(t);
break;
}
}
}
}
#endregion #region 将程序集中的所有符合条件的类型全部注册到 IServiceCollection 中 重载2
/// <summary>
/// 将程序集中的所有符合条件的类型全部注册到 IServiceCollection 中
/// </summary>
/// <param name="services">IServiceCollection</param>
/// <param name="AassemblyName">程序集名字</param>
/// <param name="wherelambda">过滤类型的表达式</param>
public static void AutoRegisterServicesFromAssembly(this IServiceCollection services,
string AassemblyName, Func<Type, bool> wherelambda)
{
//根据程序集的名字 获取程序集中所有的类型
Type[] types = GetTypesByAssemblyName(AassemblyName);
//过滤上述程序集 首先按照传进来的条件进行过滤 接着要求Type必须是类,而且不能是抽象类
IEnumerable<Type> _types = types.Where(wherelambda).Where(t => t.IsClass && !t.IsAbstract);
foreach (var t in _types)
{
IEnumerable<Attribute> attrs = t.GetCustomAttributes();
//遍历类的所有特性
foreach (var attr in attrs)
{
//如果在其特性中发现特性是 UseDIAttribute 特性 就将这个类注册到DI容器中去
//并跳出当前的循环 开始对下一个类进行循环
if (attr is UseDIAttribute)
{
services.AutoRegisterService(t);
break;
}
}
}
}
#endregion
}
}

4.在webapi的startup.cs类中注册 需要处理的程序集:

ASP.NET Core 程序集注入(一)的更多相关文章

  1. # ASP.NET Core依赖注入解读&使用Autofac替代实现

    标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Aut ...

  2. 实现BUG自动检测 - ASP.NET Core依赖注入

    我个人比较懒,能自动做的事绝不手动做,最近在用ASP.NET Core写一个项目,过程中会积累一些方便的工具类或框架,分享出来欢迎大家点评. 如果以后有时间的话,我打算写一个系列的[实现BUG自动检测 ...

  3. [译]ASP.NET Core依赖注入深入讨论

    原文链接:ASP.NET Core Dependency Injection Deep Dive - Joonas W's blog 这篇文章我们来深入探讨ASP.NET Core.MVC Core中 ...

  4. asp.net core 依赖注入几种常见情况

    先读一篇注入入门 全面理解 ASP.NET Core 依赖注入, 学习一下基本使用 然后学习一招, 不使用接口规范, 直接写功能类, 一般情况下可以用来做单例. 参考https://www.cnblo ...

  5. ASP.NET Core依赖注入——依赖注入最佳实践

    在这篇文章中,我们将深入研究.NET Core和ASP.NET Core MVC中的依赖注入,将介绍几乎所有可能的选项,依赖注入是ASP.Net Core的核心,我将分享在ASP.Net Core应用 ...

  6. 自动化CodeReview - ASP.NET Core依赖注入

    自动化CodeReview系列目录 自动化CodeReview - ASP.NET Core依赖注入 自动化CodeReview - ASP.NET Core请求参数验证 我个人比较懒,能自动做的事绝 ...

  7. ASP.NET Core 依赖注入最佳实践——提示与技巧

    在这篇文章,我将分享一些在ASP.NET Core程序中使用依赖注入的个人经验和建议.这些原则背后的动机如下: 高效地设计服务和它们的依赖. 预防多线程问题. 预防内存泄漏. 预防潜在的BUG. 这篇 ...

  8. ASP.NET Core依赖注入最佳实践,提示&技巧

    分享翻译一篇Abp框架作者(Halil İbrahim Kalkan)关于ASP.NET Core依赖注入的博文. 在本文中,我将分享我在ASP.NET Core应用程序中使用依赖注入的经验和建议. ...

  9. ASP.NET Core依赖注入解读&使用Autofac替代实现【转载】

    ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Autofac实现和自定义实现扩展方法 3.1 安装Autof ...

  10. ASP.NET Core 依赖注入基本用法

    ASP.NET Core 依赖注入 ASP.NET Core从框架层对依赖注入提供支持.也就是说,如果你不了解依赖注入,将很难适应 ASP.NET Core的开发模式.本文将介绍依赖注入的基本概念,并 ...

随机推荐

  1. Android 13 - Media框架 - 异步消息机制

    关注公众号免费阅读全文,进入音视频开发技术分享群! b7693967-317e-4c46-96d3-d40d9d87e382 由于网上已经有许多优秀的博文讲解了Android的异步消息机制(ALoop ...

  2. UILabel的DrawDrect方法

    一.问题 如果继承UILabel实现自己的一个Label,并且在子类的DrawRect方法中留空,什么都不写,会发生什么? 代码如下: VC @interface ViewController () ...

  3. 前端使用 Konva 实现可视化设计器(12)- 连接线 - 直线

    这一章实现的连接线,目前仅支持直线连接,为了能够不影响原有的其它功能,尝试了2.3个实现思路,最终实测这个实现方式目前来说最为合适了. 请大家动动小手,给我一个免费的 Star 吧~ 大家如果发现了 ...

  4. WPS相关技巧

    1 标题自动编号 首先,新建一个空白word,打开.点击默认的标题样式,可以看到并不会自动编号. 接下来,就设置如何自动编号.首先选择"编号". 然后,选择"多级编号&q ...

  5. 史上最强 AI 翻译诞生了!拳打谷歌,脚踢 DeepL

    CoT 推理范式 默认情况下,大语言模型通常是直接给出问题的最终答案,中间推理过程是隐含的.不透明的,无法发挥出大模型最极致的理解能力.如果你用它来充当翻译,可能效果和传统的机器翻译也差不了太多. 如 ...

  6. Cage 字符串听课笔记

    困困困! KMP 注意到 KMP 的复杂度是均摊的,那么是否可以绕开? 注意到 KMP 实际上一个串的 ACAM,那么考虑可以类似的,在加入一个字符的同时维护 ACAM(考虑 ACAM 的构建过程,前 ...

  7. [SWPUCTF 2021 新生赛]easy_sql

    这道题呢就是很简单的sql注入,我们直接用sqlmap来跑. 首先我们打开页面可以看见提示,参数为wllm **然后我们启动虚拟机,输入sqlmap的命令:sqlmap -u "url地址/ ...

  8. ABC330

    D 记录每一行,每一列有多少个 o,然后统计答案即可. code E 想到 \(mex^{i \le n}_{i = 1} a_i \le n\) 这整个题就可做了(赛时因为没想到这个,痛失 \(47 ...

  9. Unity 3D 的NEW (堆内存)

    用容器装 在AWEKE NEW 运行时NEW 会导致分配内存时界面卡住, new class 的时候 才刷新程序帧 AWEKE 是程序启动时还没走完第一帧的开头执行 AWEKE 里面的代码 常量也在A ...

  10. gitlab私有仓库搭建

    1.Gitlab介绍 我们了解了git是以个人为中心,但是人人都得数据交互呀..python程序员每天都忙着进行py交易 交互数据的方式 使用github或者码云等公有代码仓库,托管代码的地方,谁都可 ...