c# asp.net core 3.1 自动注入

事情的原因

在进行asp.net core开发的时候,使用原生的ioc,每一个service都要注入,产生了一堆无用的配置文件,所以想有没有一种方法,通过接口或者特性直接注入

尝试

首先想到的是接口,所以我就用一个接口

    /// <summary>
    /// 创建一个接口,用于被类实现
    /// </summary>
    interface IService
    {
    }

然后在要注入的地方,实现这个类

    /// <summary>
    /// service层
    /// </summary>
    public class Service:IService
    {
        public string GetName()
        {
            return "This is Class";
        }
    }

使用扩展方法,里面写一个反射,获取这个接口的所有类

/// <summary>
/// 扩展方法
/// </summary>
/// <param name="services">要扩展的类</param>
/// <returns></returns>
public static IServiceCollection AddDataService(this IServiceCollection services)
{
	//使用加载器技术,遍历所有的类,筛选实现IService接口的类,并过判断是否是类,并按照注解方式自动注入类
	AppDomain.CurrentDomain.GetAssemblies()
	                                      //找到自己的类,WeButler是自己写的命名空间
	                                      .FirstOrDefault(t => t.FullName.Contains("WeButler"))
	                                      //获取所有对象
                                          .GetTypes()
                                          //查找是否包含IService接口的类
                                          .Where(a=>a.GetInterfaces().Contains(IService))
                                          //判断是否是类
                                          .Where(a=>a.IsClass))
                                          //转换成list
                                          .ToList()
                                          //循环,并添加到di中
                                          .ForEach(t =>
                                          {
                                                  services.AddScopet(t);
                                          });
	return services;
}

然后在Startup.cs类中,实现这个重写

        public void ConfigureServices(IServiceCollection services)
        {
        	services.AddDataService();
        }

之后测试,没问题。

进阶

但是,我们要注入的类不只这一种,因为某些类需要单例注入并且,上面那种方法还要在实现一个接口,就在想能不能使用特性的方法,所以,对上面的方法进行了改造,首先要声明一个特性

    /// <summary>
    /// 自动注入
    /// 允许被继承
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
    public class DIAttribute : Attribute
    {
        public DIAttribute(Type dIType)
        {
            this.DIType = dIType;
        }
        public DIAttribute()
        {
            DIType = Type.OTHER;
        }
        public Type DIType { get; }

    }
    /// <summary>
    /// 注入类型选择
    /// </summary>
    public enum Type
    {
        /// <summary>
        /// 单例模式
        /// </summary>
        SINGLETON,
        /// <summary>
        /// 其他模式
        /// </summary>
        OTHER
    }

然后我们对刚刚的要注入的类进行改造

 /// <summary>
    /// service层
    /// </summary>
    [DI]
    public class Service
    {
        public string GetName()
        {
            return "This is Class";
        }
    }

只需要加上DI特性就好了,其他的我们还是用刚刚的扩展方法来做

        public static IServiceCollection AddDataService(this IServiceCollection services)
        {
            #region 处理依赖注入
            //使用加载器技术,遍历所有的类,筛选标记注解DI的类,并过滤掉抽象类,并按照注解方式自动注入类
            AppDomain.CurrentDomain.GetAssemblies()
                                                  //找到自己的类
                                                  .FirstOrDefault(t => t.FullName.Contains("WeButler"))
                                                  //获取所有对象
                                                  .GetTypes()
                                                  //查找是否包含DI特性并且查看是否是抽象类
                                                  .Where(a => a.GetCustomAttributes(true).Select(t => t.GetType()).Contains(typeof(DIAttribute)) && !a.IsAbstract)
                                                  //转换成list
                                                  .ToList()
                                                  //循环
                                                  .ForEach(t =>
                                                  {
                                                      var Di = (DIAttribute)t.GetCustomAttributes(true).FirstOrDefault(d => d.GetType() == typeof(DIAttribute));
                                                      switch (Di.DIType)
                                                      {
                                                          case Attributes.Type.SINGLETON:
                                                              services.AddSingleton(t);
                                                              break;
                                                          case Attributes.Type.OTHER:
                                                              services.AddScoped(t);
                                                              break;
                                                          default:
                                                              services.AddScoped(t);
                                                              break;
                                                      }
                                                  });
            #endregion
            return services;
        }

还是使用Startup.cs实现这个方法。
测试后发现完全没问题,可以注入。

第一次写博客,可能写的不是很好,欢迎指正

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值