using System; using System.Threading; using System.Threading.Tasks; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Promotion; using Microsoft.Extensions.DependencyInjection; namespace GB5Shared.Promotion { // ============================================================ // PromotionBridgeService — the shared server-side logic behind every module's own // three PromotionBridge endpoints (ExportForPromotion/ValidateForPromotion/ImportPromoted). // // Deliberately entity-agnostic: it just resolves the locally-registered IPromotableEntity for // a given EntityTypeCode (the module's own keyed DI — e.g. TMSModule.Register() keys // TrainingProgrammePromotionAdapter under "TRAININGPROGRAMME") and calls it, exactly the same // resolution PromotionBLL already performs in-process for GB5Framework's own entities. Each // owning module gets three thin FastEndpoints that call these three methods — see // PromotionBridgeDTOs.cs for why this exists instead of a direct BLL reference. // ============================================================ public static class PromotionBridgeService { public static async Task ExportAsync( IServiceProvider serviceProvider, string entityTypeCode, int originEntityId, LoginDTO login, CancellationToken ct) { var entity = Resolve(serviceProvider, entityTypeCode); return await entity.ExportForPromotionAsync(originEntityId, login, ct).ConfigureAwait(false); } public static async Task ValidateAsync( IServiceProvider serviceProvider, PromotionBundleDTO bundle, CancellationToken ct) { var entity = Resolve(serviceProvider, bundle.EntityTypeCode); return await entity.ValidateForPromotionAsync(bundle, ct).ConfigureAwait(false); } public static async Task ImportAsync( IServiceProvider serviceProvider, PromotionBundleDTO bundle, byte destinationSourceType, int? existingDestinationId, LoginDTO login, CancellationToken ct) { var entity = Resolve(serviceProvider, bundle.EntityTypeCode); return await entity.ImportPromotedAsync(bundle, destinationSourceType, existingDestinationId, login, ct) .ConfigureAwait(false); } private static IPromotableEntity Resolve(IServiceProvider serviceProvider, string entityTypeCode) { if (string.IsNullOrWhiteSpace(entityTypeCode)) throw new InvalidOperationException("EntityTypeCode is required."); return serviceProvider.GetKeyedService(entityTypeCode) ?? throw new InvalidOperationException( $"No IPromotableEntity registered locally for EntityTypeCode '{entityTypeCode}'."); } } }