using MAX.Core.DependencyInjection; using MAX.Core.Interfaces; using MAX.Core.Logger; 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; namespace MAX.Framework.DependencyInjection { /// /// IOC 注册入口(由宿主 Program.cs 调用) /// public static class ServiceCollectionExtensions { private static readonly Type[] DependencyMarkers = [ typeof(ISingletonDependency), typeof(IScopedDependency), typeof(ITransientDependency), ]; /// /// 添加框架注册 /// public static IServiceCollection AddStore(this IHostApplicationBuilder host) { //host.Services.AddSingleton(NLogger.Instance);//注册log IEnumerable assemblies = GetApplicationAssemblies(); // 同一个类可能同时实现 IStartup 与 IModule,这里缓存实例,保证两个阶段拿到的是同一个对象 Dictionary instances = []; return AddStoreCore(host, assemblies, instances); } /// /// 注册应用服务的公共实现:宿主入口(builder.AddStoreHub())与 入口共用。 /// internal static IServiceCollection AddStoreCore( IHostApplicationBuilder host, IEnumerable assemblies, IDictionary instances) { RegisterDependencyMarkers(host.Services, assemblies); RunModules(host, assemblies, instances); RunStartups(host.Services, assemblies, instances); host.Services.AddControllers(options => { options.Filters.Add(); options.Filters.Add(); }).ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { // 取出所有校验错误信息,拼成一个字符串(或者只取第一个) var errors = context.ModelState .Where(e => e.Value?.Errors.Count > 0) .SelectMany(e => e.Value!.Errors.Select(err => err.ErrorMessage)) .ToList(); var msg = string.Join("; ", errors); var result = ApiResult.Fail(msg, ResultCode.ValidationError); return new ObjectResult(result) { StatusCode = 200 // 和其他接口保持一致,用Code表达失败,而不是HTTP 400 }; }; }); return host.Services; } /// /// 自动注册标记接口(ISingletonDependency / IScopedDependency / ITransientDependency)的实现类型 /// private static void RegisterDependencyMarkers(IServiceCollection services, IEnumerable assemblies) { foreach (Type type in GetConcreteTypes(assemblies)) { Debug.WriteLine(type.Namespace); Type? marker = DependencyMarkers.FirstOrDefault(m => m.IsAssignableFrom(type)); if (marker is null) { continue; } ServiceLifetime lifetime = marker == typeof(ISingletonDependency) ? ServiceLifetime.Singleton : marker == typeof(IScopedDependency) ? ServiceLifetime.Scoped : ServiceLifetime.Transient; // 注册为自身 services.Add(new ServiceDescriptor(type, type, lifetime)); // 注册为实现的接口(排除标记接口与系统接口) foreach (Type iface in type.GetInterfaces()) { if (DependencyMarkers.Contains(iface) || IsSystemInterface(iface)) { continue; } services.Add(new ServiceDescriptor(iface, type, lifetime)); } } } private static IEnumerable Startups = []; /// /// 发现所有 实现,按 降序执行 /// private static void RunStartups(IServiceCollection services, IEnumerable assemblies, IDictionary instances) { IServiceRegistrar registrar = new ServiceRegistrarProxy(services); Startups = CreateInstances(assemblies, instances).OrderByDescending(s => s.Priority); foreach (IStartup startup in Startups) { startup.Initialize(); startup.Register(registrar); } } private static IEnumerable Modules = []; /// /// 执行所有模块的服务注册阶段() /// private static void RunModules(IHostApplicationBuilder host, IEnumerable assemblies, IDictionary instances) { Modules = CreateInstances(assemblies, instances).OrderByDescending(s => s.Priority); foreach (IModule module in Modules) { try { module.AddModule(host); } catch (Exception ex) { // 带上模块名,避免只看到一个没有上下文的异常 throw new InvalidOperationException($"模块 {module.GetType().FullName} 的 AddModule 执行失败。", ex); } } } /// /// 反射创建(或复用)所有实现 的具体类型实例 /// private static IEnumerable CreateInstances(IEnumerable assemblies, IDictionary instances) where T : class { foreach (Type type in GetConcreteTypes(assemblies).Where(t => typeof(T).IsAssignableFrom(t))) { if (!instances.TryGetValue(type, out object? instance)) { instance = Activator.CreateInstance(type, true) ?? throw new InvalidOperationException($"无法创建 {type.FullName} 的实例(需要有参数量为 0 的构造函数)。"); instances[type] = instance; } yield return (T)instance; } } private static IEnumerable GetConcreteTypes(IEnumerable assemblies) { return assemblies .SelectMany(SafeGetTypes) .Where(t => t.IsClass && !t.IsAbstract && !t.IsGenericTypeDefinition); } private static IEnumerable SafeGetTypes(Assembly assembly) { try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.OfType(); } } /// /// 应用程序集(模块、Startup 都从这里发现) /// internal static IEnumerable GetApplicationAssemblies() { // 使用 AppTypeFinder:扫描应用输出目录 + 已加载程序集, return StoreAppTypeFinder.Current.GetAssemblies(); } private static bool IsSystemInterface(Type type) { return type.Namespace is null || type.Namespace.StartsWith("System", StringComparison.Ordinal) || type.Namespace.StartsWith("Microsoft", StringComparison.Ordinal); } public static IApplicationBuilder UseStore(this IApplicationBuilder app) { app.UseMiddleware(); foreach (IStartup startup in Startups) { startup.Start((app as IHost).Services); } foreach (IModule module in Modules) { module.UseModule(app); } return app; } } }