using Blog.Core.Common.Core; using Blog.Core.Common.Extensions; using Blog.Core.Common.HttpContextUser; using Blog.Core.Common.Option.Core; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Blog.Core.Common; public class App { static App() { EffectiveTypes = Assemblies.SelectMany(GetTypes); } private static bool _isRun; /// 是否正在运行 public static bool IsBuild { get; set; } public static bool IsRun { get => _isRun; set => _isRun = IsBuild = value; } /// 应用有效程序集 public static readonly IEnumerable Assemblies = RuntimeExtension.GetAllAssemblies(); /// 有效程序集类型 public static readonly IEnumerable EffectiveTypes; /// 优先使用App.GetService()手动获取服务 public static IServiceProvider RootServices => IsRun || IsBuild ? InternalApp.RootServices : null; /// 获取Web主机环境,如,是否是开发环境,生产环境等 public static IWebHostEnvironment WebHostEnvironment => InternalApp.WebHostEnvironment; /// 获取泛型主机环境,如,是否是开发环境,生产环境等 public static IHostEnvironment HostEnvironment => InternalApp.HostEnvironment; /// 全局配置选项 public static IConfiguration Configuration => InternalApp.Configuration; /// /// 获取请求上下文 /// public static HttpContext HttpContext => RootServices?.GetService()?.HttpContext; public static IUser User => GetService(); #region Service /// 解析服务提供器 /// /// /// /// public static IServiceProvider GetServiceProvider(Type serviceType, bool mustBuild = false, bool throwException = true) { //获取请求生存周期的服务 if (HttpContext?.RequestServices != null) return HttpContext.RequestServices; if (App.RootServices != null) { return RootServices; } //单例 if (InternalApp.InternalServices .Where(u => u.ServiceType == (serviceType.IsGenericType ? serviceType.GetGenericTypeDefinition() : serviceType)) .Any(u => u.Lifetime == ServiceLifetime.Singleton)) { return RootServices ?? InternalApp.InternalServices.BuildServiceProvider(); } if (mustBuild) { if (throwException) { throw new ApplicationException("当前不可用,必须要等到 WebApplication Build后"); } return default; } ServiceProvider serviceProvider = InternalApp.InternalServices.BuildServiceProvider(); return serviceProvider; } public static TService GetService(bool mustBuild = true) where TService : class => App.GetService(typeof(TService), null, mustBuild) as TService; /// 获取请求生存周期的服务 /// /// /// /// public static TService GetService(IServiceProvider serviceProvider, bool mustBuild = true) where TService : class => (serviceProvider ?? App.GetServiceProvider(typeof(TService), mustBuild, false))?.GetService(); /// 获取请求生存周期的服务 /// /// /// /// public static object GetService(Type type, IServiceProvider serviceProvider = null, bool mustBuild = true) => (serviceProvider ?? App.GetServiceProvider(type, mustBuild, false))?.GetService(type); #endregion #region private /// 加载程序集中的所有类型 /// /// private static IEnumerable GetTypes(Assembly ass) { Type[] source = Array.Empty(); try { source = ass.GetTypes(); } catch { $@"Error load `{ass.FullName}` assembly.".WriteErrorLine(); } return source.Where(u => u.IsPublic); } #endregion #region Options /// 获取配置 /// 强类型选项类 /// TOptions public static TOptions GetConfig() where TOptions : class, IConfigurableOptions { TOptions instance = App.Configuration .GetSection(ConfigurableOptions.GetConfigurationPath(typeof(TOptions))) .Get(); return instance; } /// 获取选项 /// 强类型选项类 /// /// TOptions public static TOptions GetOptions(IServiceProvider serviceProvider = null) where TOptions : class, new() { IOptions service = App.GetService>(serviceProvider ?? App.RootServices, false); return service?.Value; } /// 获取选项 /// 强类型选项类 /// /// TOptions public static TOptions GetOptionsMonitor(IServiceProvider serviceProvider = null) where TOptions : class, new() { IOptionsMonitor service = App.GetService>(serviceProvider ?? App.RootServices, false); return service?.CurrentValue; } /// 获取选项 /// 强类型选项类 /// /// TOptions public static TOptions GetOptionsSnapshot(IServiceProvider serviceProvider = null) where TOptions : class, new() { IOptionsSnapshot service = App.GetService>(serviceProvider, false); return service?.Value; } #endregion }