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);
}
}
}