1. 程式人生 > 其它 >netcore依賴注入通過反射簡化

netcore依賴注入通過反射簡化

aspnetcore裡面用到許多的service,好多業務程式碼都要通過Service.AddScoped、Singleton、Transient等注入進去,類太多了寫起來和管理起來都很麻煩,所以借鑑了一下github上面的專案稍微刪減了一下下,最後會給出參考連結和git原始碼。

專案結構如下,

這裡面有些約定的東西一定要遵守,否則會出錯,還有webapi必須要引用business和ibusiness,只引用ibusiness是不行的。

核心程式碼如下:

 1 using Microsoft.Extensions.DependencyInjection;
 2 using System;
3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using My.Project.Ioc.Core.IService; 8 9 namespace My.Project.Ioc.Core.Extensions 10 { 11 public static partial class ServiceExtensions 12 { 13 /// <summary> 14 ///
自動注入擁有ITransientDependency,IScopeDependency或ISingletonDependency的類 15 /// </summary> 16 /// <param name="services">服務集合</param> 17 /// <returns></returns> 18 public static IServiceCollection AddFxServices(this IServiceCollection services) 19 {
20 Dictionary<Type, ServiceLifetime> lifeTimeMap = new Dictionary<Type, ServiceLifetime> 21 { 22 { typeof(ITransientDependency), ServiceLifetime.Transient}, 23 { typeof(IScopedDependency),ServiceLifetime.Scoped}, 24 { typeof(ISingletonDependency),ServiceLifetime.Singleton} 25 }; 26 27 GlobalData.AllFxTypes.ForEach(aType => 28 { 29 lifeTimeMap.ToList().ForEach(aMap => 30 { 31 var theDependency = aMap.Key; 32 if (theDependency.IsAssignableFrom(aType) && theDependency != aType && !aType.IsAbstract && aType.IsClass) 33 { 34 //注入實現 35 services.Add(new ServiceDescriptor(aType, aType, aMap.Value)); 36 37 var interfaces = GlobalData.AllFxTypes.Where(x => x.IsAssignableFrom(aType) && x.IsInterface && x != theDependency).ToList(); 38 //有介面則注入介面 39 if (interfaces.Count > 0) 40 { 41 interfaces.ForEach(aInterface => 42 { 43 services.Add(new ServiceDescriptor(aInterface, serviceProvider => serviceProvider.GetService(aType), aMap.Value)); 44 }); 45 } 46 //無介面則注入自己 47 else 48 { 49 services.Add(new ServiceDescriptor(aType, aType, aMap.Value)); 50 } 51 } 52 }); 53 }); 54 55 return services; 56 } 57 } 58 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.IO;
 4 using System.Linq;
 5 using System.Reflection;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace My.Project.Ioc.Core
10 {
11     public static class GlobalData
12     {
13         static GlobalData()
14         {
15             string rootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
16             AllFxAssemblies = Directory.GetFiles(rootPath, "*.dll")
17                 .Where(x => new FileInfo(x).Name.Contains(FXASSEMBLY_PATTERN))
18                 .Select(x => Assembly.LoadFrom(x))
19                 .Where(x => !x.IsDynamic)
20                 .ToList();
21 
22             AllFxAssemblies.ForEach(aAssembly =>
23             {
24                 try
25                 {
26                     AllFxTypes.AddRange(aAssembly.GetTypes());
27                 }
28                 catch
29                 {
30 
31                 }
32             });
33         }
34 
35         /// <summary>
36         /// 解決方案程式集匹配名
37         /// </summary>
38         public const string FXASSEMBLY_PATTERN = "My.Project.Ioc";
39 
40         /// <summary>
41         /// 解決方案所有程式集
42         /// </summary>
43         public static readonly List<Assembly> AllFxAssemblies;
44 
45         /// <summary>
46         /// 解決方案所有自定義類
47         /// </summary>
48         public static readonly List<Type> AllFxTypes = new List<Type>();
49     }
50 }

非核心程式碼如下:

參考專案Coldairarrow/Colder.Admin.AntdVue: Admin Fx Based On .NET 5 + Ant Design Vue (github.com),有興趣的可以研究下非常不錯。當然裡面關於aop和快取方面我有另外的專案例子可以加進去改造exercise/netcore.demo/AspNetCoreEntityFrameWork at master · liuzhixin405/exercise (github.com)