利用.net Core 對程序集中的類 進行統一依賴註入
阿新 • • 發佈:2018-08-19
info lis posit sem main HERE tasks ner assembly
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 對程序集中的類 進行統一依賴註入