加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 05:06:17 所属栏目:百科 来源:网络整理
导读:1.创建特性 用于标注依赖注入 using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; namespace Util.Attributes{ /// summary /// 标注要运用DI的类 被此属性标注的类 要被注册到依赖注入容器中 并且可以指定

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读