非依赖注入管道中获取所有服务
1.导入包
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
2.配置RuntimeExtension类
public static class RuntimeExtension
{
/// <summary>
/// 获取项目程序集,排除所有的系统程序集(Microsoft.***、System.***等)、Nuget下载包
/// </summary>
/// <returns></returns>
public static IList<Assembly> GetAllAssemblies()
{
var list = new List<Assembly>();
var deps = DependencyContext.Default;
//只加载项目中的程序集
var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type == "project"); //排除所有的系统程序集、Nuget下载包
foreach (var lib in libs)
{
try
{
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
list.Add(assembly);
}
catch (Exception e)
{
Log.Debug(e, "GetAllAssemblies Exception:{ex}", e.Message);
}
}
return list;
}
public static Assembly GetAssembly(string assemblyName)
{
return GetAllAssemblies().FirstOrDefault(assembly => assembly.FullName.Contains(assemblyName));
}
public static IList<Type> GetAllTypes()
{
var list = new List<Type>();
foreach (var assembly in GetAllAssemblies())
{
var typeInfos = assembly.DefinedTypes;
foreach (var typeInfo in typeInfos)
{
list.Add(typeInfo.AsType());
}
}
return list;
}
public static IList<Type> GetTypesByAssembly(string assemblyName)
{
var list = new List<Type>();
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyName));
var typeInfos = assembly.DefinedTypes;
foreach (var typeInfo in typeInfos)
{
list.Add(typeInfo.AsType());
}
return list;
}
public static Type GetImplementType(string typeName, Type baseInterfaceType)
{
return GetAllTypes().FirstOrDefault(t =>
{
if (t.Name == typeName &&
t.GetTypeInfo().GetInterfaces().Any(b => b.Name == baseInterfaceType.Name))
{
var typeInfo = t.GetTypeInfo();
return typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.IsGenericType;
}
return false;
});
}
}
3.配置InternalApp类
/// <summary>
/// 内部只用于初始化使用
/// </summary>
public static class InternalApp
{
internal static IServiceCollection InternalServices;
/// <summary>
/// 根服务
/// </summary>
internal static IServiceProvider RootServices;
/// <summary>
/// 获取web主机环境
/// </summary>
internal static IWebHostEnvironment WebHostEnvironment;
/// <summary>
/// 获取泛型主机环境
/// </summary>
internal static IHostEnvironment HostEnvironment;
/// <summary>
/// 配置对象
/// </summary>
internal static IConfiguration Configuration;
public static void ConfigureApplication(this WebApplicationBuilder wab)
{
WebHostEnvironment = wab.Environment;
HostEnvironment = wab.Environment;
InternalServices = wab.Services;
}
public static void ConfigureApplication(this IConfiguration configuration)
{
Configuration = configuration;
}
public static void ConfigureApplication(this IHost app)
{
RootServices = app.Services;
}
}
4.配置IUser接口
public interface IUser
{
string Name { get; }
long ID { get; }
long TenantId { get; }
bool IsAuthenticated();
IEnumerable<Claim> GetClaimsIdentity();
List<string> GetClaimValueByType(string ClaimType);
string GetToken();
List<string> GetUserInfoFromToken(string ClaimType);
}
5.配置APP类
public class App
{
static App()
{
EffectiveTypes = Assemblies.SelectMany(GetTypes);
}
private static bool _isRun;
/// <summary>是否正在运行</summary>
public static bool IsBuild { get; set; }
public static bool IsRun
{
get => _isRun;
set => _isRun = IsBuild = value;
}
/// <summary>应用有效程序集</summary>
public static readonly IEnumerable<Assembly> Assemblies = RuntimeExtension.GetAllAssemblies();
/// <summary>有效程序集类型</summary>
public static readonly IEnumerable<Type> EffectiveTypes;
/// <summary>优先使用App.GetService()手动获取服务</summary>
public static IServiceProvider RootServices => IsRun || IsBuild ? InternalApp.RootServices : null;
/// <summary>获取Web主机环境,如,是否是开发环境,生产环境等</summary>
public static IWebHostEnvironment WebHostEnvironment => InternalApp.WebHostEnvironment;
/// <summary>获取泛型主机环境,如,是否是开发环境,生产环境等</summary>
public static IHostEnvironment HostEnvironment => InternalApp.HostEnvironment;
/// <summary>全局配置选项</summary>
public static IConfiguration Configuration => InternalApp.Configuration;
/// <summary>
/// 获取请求上下文
/// </summary>
public static HttpContext HttpContext => RootServices?.GetService<IHttpContextAccessor>()?.HttpContext;
public static IUser User => GetService<IUser>();
#region Service
/// <summary>解析服务提供器</summary>
/// <param name="serviceType"></param>
/// <param name="mustBuild"></param>
/// <param name="throwException"></param>
/// <returns></returns>
public static IServiceProvider GetServiceProvider(Type serviceType, bool mustBuild = false, bool throwException = true)
{
if (HostEnvironment == null || RootServices != null &&
InternalApp.InternalServices
.Where(u =>
u.ServiceType ==
(serviceType.IsGenericType ? serviceType.GetGenericTypeDefinition() : serviceType))
.Any(u => u.Lifetime == ServiceLifetime.Singleton))
return RootServices;
//获取请求生存周期的服务
if (HttpContext?.RequestServices != null)
return HttpContext.RequestServices;
if (RootServices != null)
{
IServiceScope scope = RootServices.CreateScope();
return scope.ServiceProvider;
}
if (mustBuild)
{
if (throwException)
{
throw new ApplicationException("当前不可用,必须要等到 WebApplication Build后");
}
return default;
}
ServiceProvider serviceProvider = InternalApp.InternalServices.BuildServiceProvider();
return serviceProvider;
}
public static TService GetService<TService>(bool mustBuild = true) where TService : class =>
GetService(typeof(TService), null, mustBuild) as TService;
/// <summary>获取请求生存周期的服务</summary>
/// <typeparam name="TService"></typeparam>
/// <param name="serviceProvider"></param>
/// <param name="mustBuild"></param>
/// <returns></returns>
public static TService GetService<TService>(IServiceProvider serviceProvider, bool mustBuild = true)
where TService : class => (serviceProvider ?? GetServiceProvider(typeof(TService), mustBuild, false))?.GetService<TService>();
/// <summary>获取请求生存周期的服务</summary>
/// <param name="type"></param>
/// <param name="serviceProvider"></param>
/// <param name="mustBuild"></param>
/// <returns></returns>
public static object GetService(Type type, IServiceProvider serviceProvider = null, bool mustBuild = true) =>
(serviceProvider ?? GetServiceProvider(type, mustBuild, false))?.GetService(type);
#endregion
#region private
/// <summary>加载程序集中的所有类型</summary>
/// <param name="ass"></param>
/// <returns></returns>
private static IEnumerable<Type> GetTypes(Assembly ass)
{
Type[] source = Array.Empty<Type>();
try
{
source = ass.GetTypes();
}
catch
{
Console.WriteLine($@"Error load `{ass.FullName}` assembly.");
}
return source.Where(u => u.IsPublic);
}
#endregion
#region Options
/// <summary>获取配置</summary>
/// <typeparam name="TOptions">强类型选项类</typeparam>
/// <returns>TOptions</returns>
public static TOptions GetConfig<TOptions>()
where TOptions : class, IConfigurableOptions
{
TOptions instance = Configuration
.GetSection(ConfigurableOptions.GetConfigurationPath(typeof(TOptions)))
.Get<TOptions>();
return instance;
}
/// <summary>获取选项</summary>
/// <typeparam name="TOptions">强类型选项类</typeparam>
/// <param name="serviceProvider"></param>
/// <returns>TOptions</returns>
public static TOptions GetOptions<TOptions>(IServiceProvider serviceProvider = null) where TOptions : class, new()
{
IOptions<TOptions> service = GetService<IOptions<TOptions>>(serviceProvider ?? RootServices, false);
return service?.Value;
}
/// <summary>获取选项</summary>
/// <typeparam name="TOptions">强类型选项类</typeparam>
/// <param name="serviceProvider"></param>
/// <returns>TOptions</returns>
public static TOptions GetOptionsMonitor<TOptions>(IServiceProvider serviceProvider = null)
where TOptions : class, new()
{
IOptionsMonitor<TOptions> service =
GetService<IOptionsMonitor<TOptions>>(serviceProvider ?? RootServices, false);
return service?.CurrentValue;
}
/// <summary>获取选项</summary>
/// <typeparam name="TOptions">强类型选项类</typeparam>
/// <param name="serviceProvider"></param>
/// <returns>TOptions</returns>
public static TOptions GetOptionsSnapshot<TOptions>(IServiceProvider serviceProvider = null)
where TOptions : class, new()
{
IOptionsSnapshot<TOptions> service = GetService<IOptionsSnapshot<TOptions>>(serviceProvider, false);
return service?.Value;
}
#endregion
}
6.配置ApplicationSetup类,增加扩展方法
public static class ApplicationSetup
{
public static void UseApplicationSetup(this WebApplication app)
{
app.Lifetime.ApplicationStarted.Register(() =>
{
App.IsRun = true;
});
app.Lifetime.ApplicationStopped.Register(() =>
{
App.IsRun = false;
// 清除日志
Log.CloseAndFlush();
});
}
}
7.在program.cs文件中注册服务

.ConfigureAppConfiguration((hostingContext, config) =>
{
hostingContext.Configuration.ConfigureApplication();
});
// 非依赖注入管道中获取所有服务(App类)
app.ConfigureApplication();
app.UseApplicationSetup();
8.在control层中使用

// 直接通过APP类获取以往需要依赖注入才能获得的对象
var roleServiceObjNew = App.GetService<IBaseService<Role, RoleVo>>(false);
var roleList = await roleServiceObjNew.Query();
// 直接通过APP类获取类似appsettings.json配置信息
RedisOptions redisOptions = App.GetOptions<RedisOptions>();
Console.WriteLine(JsonConvert.SerializeObject(redisOptions));

浙公网安备 33010602011771号