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實現這個方法。
測試后發現完全沒問題,可以注入。

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM