using NCC; using NCC.Dependency; using NCC.UnifyResult; using Microsoft.Extensions.Hosting; using System; using System.Linq; using System.Reflection; namespace Microsoft.Extensions.DependencyInjection { /// /// 应用服务集合拓展类(由框架内部调用) /// [SuppressSniffer] public static class AppServiceCollectionExtensions { /// /// Mvc 注入基础配置(带Swagger) /// /// Mvc构建器 /// /// IMvcBuilder public static IMvcBuilder AddInject(this IMvcBuilder mvcBuilder, Action configure = null) { mvcBuilder.Services.AddInject(configure); return mvcBuilder; } /// /// 服务注入基础配置(带Swagger) /// /// 服务集合 /// IMvcBuilder /// public static IServiceCollection AddInject(this IServiceCollection services, Action configure = null) { // 载入服务配置选项 var configureOptions = new InjectServiceOptions(); configure?.Invoke(configureOptions); services.AddSpecificationDocuments(configureOptions?.SpecificationDocumentConfigure) .AddDynamicApiControllers() .AddDataValidation(configureOptions?.DataValidationConfigure) .AddFriendlyException(configureOptions?.FriendlyExceptionConfigure); return services; } /// /// Mvc 注入基础配置 /// /// Mvc构建器 /// /// IMvcBuilder public static IMvcBuilder AddInjectBase(this IMvcBuilder mvcBuilder, Action configure = null) { mvcBuilder.Services.AddInjectBase(configure); return mvcBuilder; } /// /// Mvc 注入基础配置 /// /// 服务集合 /// /// IMvcBuilder public static IServiceCollection AddInjectBase(this IServiceCollection services, Action configure = null) { // 载入服务配置选项 var configureOptions = new InjectServiceOptions(); configure?.Invoke(configureOptions); services.AddDataValidation(configureOptions?.DataValidationConfigure) .AddFriendlyException(configureOptions?.FriendlyExceptionConfigure); return services; } /// /// Mvc 注入基础配置和规范化结果 /// /// /// /// public static IMvcBuilder AddInjectWithUnifyResult(this IMvcBuilder mvcBuilder, Action configure = null) { mvcBuilder.Services.AddInjectWithUnifyResult(configure); return mvcBuilder; } /// /// 注入基础配置和规范化结果 /// /// /// /// public static IServiceCollection AddInjectWithUnifyResult(this IServiceCollection services, Action configure = null) { services.AddInject(configure) .AddUnifyResult(); return services; } /// /// Mvc 注入基础配置和规范化结果 /// /// /// /// /// public static IMvcBuilder AddInjectWithUnifyResult(this IMvcBuilder mvcBuilder, Action configure = null) where TUnifyResultProvider : class, IUnifyResultProvider { mvcBuilder.Services.AddInjectWithUnifyResult(configure); return mvcBuilder; } /// /// Mvc 注入基础配置和规范化结果 /// /// /// /// /// public static IServiceCollection AddInjectWithUnifyResult(this IServiceCollection services, Action configure = null) where TUnifyResultProvider : class, IUnifyResultProvider { services.AddInject(configure) .AddUnifyResult(); return services; } /// /// 自动添加主机服务 /// /// /// public static IServiceCollection AddAppHostedService(this IServiceCollection services) { // 获取所有 BackgroundService 类型 var backgroundServiceTypes = App.EffectiveTypes.Where(u => typeof(BackgroundService).IsAssignableFrom(u)); var addHostServiceMethod = typeof(ServiceCollectionHostedServiceExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public) .Where(u => u.Name.Equals("AddHostedService") && u.IsGenericMethod && u.GetParameters().Length == 1) .FirstOrDefault(); foreach (var type in backgroundServiceTypes) { addHostServiceMethod.MakeGenericMethod(type).Invoke(null, new object[] { services }); } return services; } /// /// 供控制台构建根服务 /// /// /// public static void Build(this IServiceCollection services) { var serviceProvider = services.BuildServiceProvider(false); // 存储根服务 InternalApp.RootServices = serviceProvider; } /// /// 添加应用配置 /// /// 服务集合 /// 服务配置 /// 服务集合 internal static IServiceCollection AddApp(this IServiceCollection services, Action configure = null) { // 注册全局配置选项 services.AddConfigurableOptions(); // 注册内存和分布式内存 services.AddMemoryCache(); services.AddDistributedMemoryCache(); // 注册全局依赖注入 services.AddDependencyInjection(); // 注册全局 Startup 扫描 services.AddStartups(); // 添加对象映射 services.AddObjectMapper(); // 自定义服务 configure?.Invoke(services); return services; } /// /// 添加 Startup 自动扫描 /// /// 服务集合 /// 服务集合 internal static IServiceCollection AddStartups(this IServiceCollection services) { // 扫描所有继承 AppStartup 的类 var startups = App.EffectiveTypes .Where(u => typeof(AppStartup).IsAssignableFrom(u) && u.IsClass && !u.IsAbstract && !u.IsGenericType) .OrderByDescending(u => GetStartupOrder(u)); // 注册自定义 startup foreach (var type in startups) { var startup = Activator.CreateInstance(type) as AppStartup; App.AppStartups.Add(startup); // 获取所有符合依赖注入格式的方法,如返回值void,且第一个参数是 IServiceCollection 类型 var serviceMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(u => u.ReturnType == typeof(void) && u.GetParameters().Length > 0 && u.GetParameters().First().ParameterType == typeof(IServiceCollection)); if (!serviceMethods.Any()) continue; // 自动安装属性调用 foreach (var method in serviceMethods) { method.Invoke(startup, new[] { services }); } } return services; } /// /// 获取 Startup 排序 /// /// 排序类型 /// int private static int GetStartupOrder(Type type) { return !type.IsDefined(typeof(AppStartupAttribute), true) ? 0 : type.GetCustomAttribute(true).Order; } } }