using MAX.Core.DependencyInjection; using MAX.Core.Interfaces; using MAX.Framework.Commons; using MAX.Framework.Dtos; using MAX.Framework.Interfaces; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; 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), ]; /// /// 注册应用服务: /// /// 自动注册所有实现 / / 的类型; /// 发现所有 ,按 降序执行 Initialize + Register。 /// /// public static IServiceCollection AddStoreHub(this IServiceCollection services) { IEnumerable assemblies = GetApplicationAssemblies(); RegisterDependencyMarkers(services, assemblies); RunStartups(services, assemblies); RunModules(services, assemblies); 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 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 void RunStartups(IServiceCollection services, IEnumerable assemblies) { IServiceRegistrar registrar = new ServiceRegistrarProxy(services); foreach (IStartup startup in GetConcreteTypes(assemblies) .Where(t => typeof(IStartup).IsAssignableFrom(t)) .Select(t => (IStartup)Activator.CreateInstance(t, true)!) .OrderByDescending(s => s.Priority)) { startup.Initialize(); startup.Register(registrar); } } private static void RunModules(IServiceCollection services, IEnumerable assemblies) { IServiceRegistrar registrar = new ServiceRegistrarProxy(services); foreach (IModule startup in GetConcreteTypes(assemblies) .Where(t => typeof(IModule).IsAssignableFrom(t)) .Select(t => (IModule)Activator.CreateInstance(t, true)!)) { startup.AddModule(services); } } 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(); } } private static IEnumerable GetApplicationAssemblies() { // 使用 AppTypeFinder:扫描应用输出目录 + 已加载程序集, return StoreHubAppTypeFinder.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); } } }