.Net Core中如何实现批量依赖注入——反射+特性

在.net core中使用依赖注入是很常见的,最常见的我们会使用以下三种

services.AddScoped<TestIBLL, TestBLL>();
services.AddSingleton<TestIBLL, TestBLL>();
services.AddTransient<TestIBLL, TestBLL>();

当我们的业务层内容不多的时候这样写没有什么问题,但是加入有100个BLL呢,那样一个一

个加会很麻烦,每加一个就要多写一次,而且容易忘记漏掉。

那么我们的需求是让希望能够实现批量注入,并且可以按照不同的生命周期去实现自动注入,以避免每加一个业务类,就要写一次services.AddScoped<>();

我将通过反射+特性来实现它。

 1.首先新建一个类ServiceAttribute,该类要继承Attribute,定义一个属性LifeTime,用它来接收注入时需要的生命周期,默认等于ServiceLifetime.Scoped,使用ServiceLifetime.Scoped需要导入using Microsoft.Extensions.DependencyInjection命名空间。

/// <summary>
    /// 属性形式定义生命周期
    /// 默认Scoped
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class ServiceAttribute:Attribute
    {
        public ServiceLifetime LifeTime { get; set; }
        public ServiceAttribute(ServiceLifetime serviceLifetime= ServiceLifetime.Scoped)
        {
            LifeTime = serviceLifetime;
        }
    }

2.在自己需要注入的业务类中加上ServiceAttribute特性,并给上生命周期,也可以不给,就默认是Scoped

  [Service(ServiceLifetime.Scoped)]
    public class TestBLL:TestIBLL
    {
    }
    public interface TestIBLL
    {

    }

3.核心部分,新建一个IServiceCollection的扩展方法类,取名叫ServiceCollectionExpand,定义扩展方法AddBusiness

1.获取当前程序域中的所有程序集,然后获取每个程序集中的所有type,得到其中包含有我们写的ServiceAttribute特性的类。

2.遍历types,得到每一个type所继承的接口数组和它注入的生命周期的值,然后根据生命周期实现注入, service.AddSingleton(,)和service.AddSingleton<>()不同的是传入的参数不同,前者的两个值都是type类型,后者是两个泛型

/// <summary>
    /// IServiceCollection扩展类
    /// </summary>
    public static class ServiceCollectionExpand
    {
        /// <summary>
        /// 按特性中的生命周期注入业务组件
        /// </summary>
        /// <param name="service"></param>
        public static void AddBusiness(this IServiceCollection service)
        {
            //获取有ServiceAttribute特性的所有类
            List<Type> types = AppDomain.CurrentDomain
                .GetAssemblies()
                .SelectMany(x => x.GetTypes())
                .Where(t => t.IsClass && !t.IsAbstract 
                        && t.GetCustomAttributes(typeof(ServiceAttribute), false).Length > 0
                        )
                .ToList();

            types.ForEach(impl=> 
            {
                //获取该类所继承的所有接口
                Type[] interfaces = impl.GetInterfaces();
                //获取该类注入的生命周期
                var lifetime = impl.GetCustomAttribute<ServiceAttribute>().LifeTime;

                interfaces.ToList().ForEach(i => 
                {
                    switch (lifetime)
                    {
                        case ServiceLifetime.Singleton:
                            service.AddSingleton(i,impl);
                            break;
                        case ServiceLifetime.Scoped:
                            service.AddScoped(i, impl);
                            break;
                        case ServiceLifetime.Transient:
                            service.AddTransient(i, impl);
                            break;
                    }
                });
            });

        }

    }

4.然后在startup类中的configureservices方法中调用扩展方法即可实现自动注入了

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();


            #region 注册业务组件
            services.AddBusiness();
            #endregion



        }

使用的话,在控制器中和以前一样使用即可。有反射的基础知识再看的话会比较容易明白。

也有很多第三方组件可以实现批量依赖注入,比如autofac,Unity等。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不想只会CRUD的猿某人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值