修改 Startup 加载 和Module 加载
This commit is contained in:
1 parent
c732ecb1d2
commit
c7fb447034
17 files changed
+462
-383
No files matched your search
@@ -3,10 +3,13 @@ using MAX.Core.Interfaces;
|
||||
using MAX.Framework.Commons;
|
||||
using MAX.Framework.Dtos;
|
||||
using MAX.Framework.Interfaces;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Win32;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
@@ -25,70 +28,37 @@ namespace MAX.Framework.DependencyInjection
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// 兼容入口:只有服务集合,没有配置与环境(模块拿到的 <see cref="ModuleContext.Configuration"/> 是空配置),
|
||||
/// 也拿不到 IConfigurationBuilder,所以模块自己的配置文件不会加载。新代码请用 <c>builder.AddStoreHub()</c>。
|
||||
/// 添加框架注册
|
||||
/// </summary>
|
||||
public static IServiceCollection AddStoreHub(this IServiceCollection services)
|
||||
{
|
||||
return services.AddStoreHub(null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带配置的注册入口:<c>builder.Services.AddStoreHub(builder.Configuration)</c>
|
||||
/// </summary>
|
||||
public static IServiceCollection AddStoreHub(this IServiceCollection services, IConfiguration? configuration)
|
||||
{
|
||||
return services.AddStoreHub(configuration, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册应用服务:
|
||||
/// <list type="number">
|
||||
/// <item>自动注册所有实现 <see cref="ISingletonDependency"/> / <see cref="IScopedDependency"/> / <see cref="ITransientDependency"/> 的类型;</item>
|
||||
/// <item>发现所有 <see cref="IStartup"/>,按 <see cref="IStartup.Priority"/> 降序执行 Initialize + Register;</item>
|
||||
/// <item>发现所有 <see cref="IModule"/>,按 <see cref="IModule.Priority"/> 降序执行 <see cref="IModule.AddModule"/>,
|
||||
/// 并把模块实例登记进容器,留给 <c>app.UseStoreHubModules()</c> 执行管道阶段。</item>
|
||||
/// </list>
|
||||
/// 这个入口不加载模块自己的配置文件,需要模块配置请用 <c>builder.AddStoreHub()</c>。
|
||||
/// </summary>
|
||||
public static IServiceCollection AddStoreHub(this IServiceCollection services, IConfiguration? configuration, IHostEnvironment? environment)
|
||||
public static IServiceCollection AddStore(this IHostApplicationBuilder host)
|
||||
{
|
||||
IEnumerable<Assembly> assemblies = GetApplicationAssemblies();
|
||||
|
||||
// 同一个类可能同时实现 IStartup 与 IModule,这里缓存实例,保证两个阶段拿到的是同一个对象
|
||||
Dictionary<Type, object> instances = [];
|
||||
ModuleRegistry modules = DiscoverModules(assemblies, instances);
|
||||
|
||||
return services.AddStoreHubCore(assemblies, modules, instances, configuration, environment);
|
||||
return AddStoreCore(host, assemblies, instances);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 注册应用服务的公共实现:宿主入口(<c>builder.AddStoreHub()</c>)与 <see cref="IServiceCollection"/> 入口共用。
|
||||
/// </summary>
|
||||
internal static IServiceCollection AddStoreHubCore(
|
||||
this IServiceCollection services,
|
||||
internal static IServiceCollection AddStoreCore(
|
||||
IHostApplicationBuilder host,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
ModuleRegistry modules,
|
||||
IDictionary<Type, object> instances,
|
||||
IConfiguration? configuration,
|
||||
IHostEnvironment? environment)
|
||||
IDictionary<Type, object> instances)
|
||||
{
|
||||
RegisterDependencyMarkers(services, assemblies);
|
||||
RunStartups(services, assemblies, instances);
|
||||
RegisterDependencyMarkers(host.Services, assemblies);
|
||||
|
||||
ModuleContext context = new(
|
||||
services,
|
||||
new ServiceRegistrarProxy(services),
|
||||
configuration ?? new ConfigurationBuilder().Build(),
|
||||
environment);
|
||||
RunModules(host, assemblies, instances);
|
||||
|
||||
RunModules(modules, context);
|
||||
|
||||
// 注册表必须在 Build() 之前进容器,UseStoreHubModules() 才拿得到
|
||||
services.AddSingleton(modules);
|
||||
RunStartups(host.Services, assemblies, instances);
|
||||
|
||||
|
||||
services.AddControllers(options =>
|
||||
|
||||
host.Services.AddControllers(options =>
|
||||
{
|
||||
options.Filters.Add<GlobalExceptionFilter>();
|
||||
options.Filters.Add<UnifyResultFilter>();
|
||||
@@ -113,7 +83,7 @@ namespace MAX.Framework.DependencyInjection
|
||||
};
|
||||
|
||||
});
|
||||
return services;
|
||||
return host.Services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -149,39 +119,33 @@ namespace MAX.Framework.DependencyInjection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<IStartup> Startups = [];
|
||||
/// <summary>
|
||||
/// 发现所有 <see cref="IStartup"/> 实现,按 <see cref="IStartup.Priority"/> 降序执行
|
||||
/// </summary>
|
||||
private static void RunStartups(IServiceCollection services, IEnumerable<Assembly> assemblies, IDictionary<Type, object> instances)
|
||||
{
|
||||
IServiceRegistrar registrar = new ServiceRegistrarProxy(services);
|
||||
|
||||
foreach (IStartup startup in CreateInstances<IStartup>(assemblies, instances).OrderByDescending(s => s.Priority))
|
||||
Startups = CreateInstances<IStartup>(assemblies, instances).OrderByDescending(s => s.Priority);
|
||||
foreach (IStartup startup in Startups)
|
||||
{
|
||||
startup.Initialize();
|
||||
startup.Register(registrar);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发现所有 <see cref="IModule"/> 实现,只创建实例,不执行任何阶段
|
||||
/// </summary>
|
||||
internal static ModuleRegistry DiscoverModules(IEnumerable<Assembly> assemblies, IDictionary<Type, object> instances)
|
||||
{
|
||||
return new ModuleRegistry([.. CreateInstances<IModule>(assemblies, instances).OrderByDescending(m => m.Priority)]);
|
||||
}
|
||||
|
||||
private static IEnumerable<IModule> Modules = [];
|
||||
/// <summary>
|
||||
/// 执行所有模块的服务注册阶段(<see cref="IModule.AddModule"/>)
|
||||
/// </summary>
|
||||
private static void RunModules(ModuleRegistry modules, ModuleContext context)
|
||||
private static void RunModules(IHostApplicationBuilder host, IEnumerable<Assembly> assemblies, IDictionary<Type, object> instances)
|
||||
{
|
||||
foreach (IModule module in modules.Modules)
|
||||
Modules = CreateInstances<IModule>(assemblies, instances).OrderByDescending(s => s.Priority);
|
||||
foreach (IModule module in Modules)
|
||||
{
|
||||
try
|
||||
{
|
||||
module.AddModule(context);
|
||||
module.AddModule(host);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -234,7 +198,7 @@ namespace MAX.Framework.DependencyInjection
|
||||
internal static IEnumerable<Assembly> GetApplicationAssemblies()
|
||||
{
|
||||
// 使用 AppTypeFinder:扫描应用输出目录 + 已加载程序集,
|
||||
return StoreHubAppTypeFinder.Current.GetAssemblies();
|
||||
return StoreAppTypeFinder.Current.GetAssemblies();
|
||||
}
|
||||
|
||||
private static bool IsSystemInterface(Type type)
|
||||
@@ -244,5 +208,20 @@ namespace MAX.Framework.DependencyInjection
|
||||
|| type.Namespace.StartsWith("Microsoft", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
|
||||
public static IApplicationBuilder UseStore(this IApplicationBuilder app)
|
||||
{
|
||||
foreach (IStartup startup in Startups)
|
||||
{
|
||||
startup.Start((app as IHost).Services);
|
||||
}
|
||||
|
||||
foreach (IModule module in Modules)
|
||||
{
|
||||
module.UseModule(app);
|
||||
}
|
||||
return app;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user