分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

利用.net Core 对程序集中的类 进行统一依赖注入

发布时间:2023-09-06 02:10责任编辑:彭小芳关键词:暂无标签

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类中注册 需要处理的程序集:

利用.net Core 对程序集中的类 进行统一依赖注入

原文地址:https://www.cnblogs.com/wholeworld/p/9502133.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved