using Masuit.Tools.AspNetCore.ResumeFileResults.Executor; using Masuit.Tools.AspNetCore.ResumeFileResults.ResumeFileResult; using Masuit.Tools.Files; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.Extensions.DependencyInjection.Extensions; using System.Reflection; using Masuit.Tools.Reflection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace Masuit.Tools.Core.AspNetCore; /// /// 依赖注入ServiceCollection容器扩展方法 /// public static class ServiceCollectionExtensions { /// /// 注入断点续传服务 /// /// /// public static IServiceCollection AddResumeFileResult(this IServiceCollection services) { services.TryAddSingleton, ResumePhysicalFileResultExecutor>(); services.TryAddSingleton, ResumeVirtualFileResultExecutor>(); services.TryAddSingleton, ResumeFileStreamResultExecutor>(); services.TryAddSingleton, ResumeFileContentResultExecutor>(); return services; } /// /// 注入7z压缩 /// /// /// public static IServiceCollection AddSevenZipCompressor(this IServiceCollection services) { services.AddHttpClient(); return services; } /// /// 自动扫描需要注册的服务,被ServiceInject标记的class可自动注入 /// /// public static void AutoRegisterServices(this IServiceCollection services) { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); services.RegisterServiceByAttribute(assemblies); services.RegisterBackgroundService(assemblies); } /// /// 自动扫描需要注册的服务,被ServiceInject标记的class可自动注入 /// /// /// public static void AutoRegisterServices(this IServiceCollection services, params Assembly[] assemblies) { services.RegisterServiceByAttribute(assemblies); services.RegisterBackgroundService(assemblies); } /// /// 通过 ServiceAttribute 批量注册服务 /// /// private static void RegisterServiceByAttribute(this IServiceCollection services, IEnumerable assemblies) { var types = assemblies.SelectMany(t => t.GetExportedTypes()).Where(t => (t.GetCustomAttributes(typeof(ServiceInjectAttribute), false).Length > 0 || t.GetInterfaces().Intersect([typeof(IScoped), typeof(ITransient), typeof(ISingleton)]).Any()) && t.IsClass && !t.IsAbstract); foreach (var type in types) { var typeInterface = type.GetInterfaces().Except([typeof(IScoped), typeof(ITransient), typeof(ISingleton)]).OrderBy(t => t.Name.HammingDistance(type.Name)).FirstOrDefault(); if (typeInterface == null) { //服务非继承自接口的直接注入 switch (type.GetCustomAttribute()?.Lifetime) { case ServiceLifetime.Singleton: services.TryAddSingleton(type); break; case ServiceLifetime.Scoped: services.TryAddScoped(type); break; case ServiceLifetime.Transient: services.TryAddTransient(type); break; default: if (type.IsImplementsOf(typeof(IScoped))) { services.TryAddScoped(type); } else if (type.IsImplementsOf(typeof(ISingleton))) { services.TryAddSingleton(type); } else if (type.IsImplementsOf(typeof(ITransient))) { services.TryAddTransient(type); } break; } } else { //服务继承自接口的和接口一起注入 switch (type.GetCustomAttribute()?.Lifetime) { case ServiceLifetime.Singleton: services.TryAddSingleton(type); services.TryAddSingleton(typeInterface, type); break; case ServiceLifetime.Scoped: services.TryAddScoped(type); services.TryAddScoped(typeInterface, type); break; case ServiceLifetime.Transient: services.TryAddTransient(type); services.TryAddTransient(typeInterface, type); break; default: if (type.IsImplementsOf(typeof(IScoped))) { services.TryAddScoped(type); services.TryAddSingleton(typeInterface, type); } else if (type.IsImplementsOf(typeof(ISingleton))) { services.TryAddSingleton(type); services.TryAddSingleton(typeInterface, type); } else if (type.IsImplementsOf(typeof(ITransient))) { services.TryAddTransient(type); services.TryAddTransient(typeInterface, type); } break; } } } } /// /// 注册后台服务 /// /// private static void RegisterBackgroundService(this IServiceCollection services, IEnumerable assemblies) { var types = assemblies.SelectMany(t => t.GetTypes()).Where(t => typeof(BackgroundService).IsAssignableFrom(t) && !t.IsAbstract); foreach (var type in types) { services.TryAddSingleton(typeof(IHostedService), type); } } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] public class ServiceInjectAttribute : Attribute { public ServiceInjectAttribute() { } public ServiceInjectAttribute(ServiceLifetime lifetime) { Lifetime = lifetime; } public ServiceLifetime Lifetime { get; set; } = ServiceLifetime.Transient; } public interface IScoped; public interface ITransient; public interface ISingleton;