using System.Reflection; using GB5Shared.DaprCache; using GB5Shared.Hosting; using GB5Shared.Promotion; namespace TMSSL; public class TMSModule : IModule { public void Register(IServiceCollection services, IConfiguration configuration) { services.AddScoped(); // Metadata Promotion — registered locally in this module's own process (HRFinanceHost), // resolved by EntityTypeCode via the exact same keyed-DI pattern FrameworkSL uses for its // own (in-process) entities. FrameworkBLL's RemoteHttpPromotionAdapter reaches this over // HTTP via the PromotionBridge endpoints in TMSSL/Endpoints/Promotion — see // GB5Shared/DTO/Promotion/PromotionBridgeDTOs.cs for why a direct reference isn't used. services.AddKeyedScoped("TRAININGPROGRAMME"); // These 3 fall outside the BLL/DAL suffix filter the Scrutor scan below uses, so they'd // otherwise never get registered (confirmed live via HRFinanceHost's /health DI pre-flight // check: TrainingCertificateBLL/AssessmentAttemptBLL degraded because ICertificatePdfPipeline/ // IAssessmentAnswerEvaluationService/IAssessmentQuestionGenerationService were never bound). services.AddScoped(); services.AddScoped(); services.AddScoped(); // Scrutor assembly scan — TMSBLL + TMSDAL + FLSBLL + FLSDAL // FLS (Feedback/Instance/Respondent) assemblies are required here because // TmsFeedbackBLL directly depends on IFlsInstanceBLL and IFlsRespondentBLL. var tmsBLLAssembly = Assembly.Load("TMSBLL"); var tmsDALAssembly = Assembly.Load("TMSDAL"); var flsBLLAssembly = Assembly.Load("FLSBLL"); var flsDALAssembly = Assembly.Load("FLSDAL"); services.Scan(scan => scan .FromAssemblies(tmsBLLAssembly, tmsDALAssembly, flsBLLAssembly, flsDALAssembly) .AddClasses(c => c.Where(t => !t.IsAbstract && !t.IsInterface && !IsCompilerGeneratedRecord(t) && (t.Name.EndsWith("BLL") || t.Name.EndsWith("DAL")))) .AsImplementedInterfaces() .WithScopedLifetime()); } public void MapEndpoints(WebApplication app) { } // Records get a compiler-generated $ method — this filters them out // so DTOs/records (e.g. TmsBatchFeedbackStatusDto) never get treated as // registerable services just because they implement IEquatable. private static bool IsCompilerGeneratedRecord(Type t) => t.GetMethod("$") != null; }