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;
}
}
}