using System.Reflection; using ECPBLL.Communication.Interfaces; using ECPSL.Communication.Hubs; using GB5Shared.DaprCache; using GB5Shared.DocumentMerge; using GB5Shared.EventLogPublish; using GB5Shared.Hosting; using GB5Shared.RecordingIntelligence; namespace ECPSL; public class EcpModule : IModule { public void Register(IServiceCollection services, IConfiguration configuration) { // SignalR (Communication only — Correspondence/Collaboration/Meeting are request/response // + async-outbox modules; real-time push for Collaboration/Meeting discussion content // goes through this same hub via the shared MENTITY-registry convention, not a hub of // their own). services.AddSignalR(options => { options.EnableDetailedErrors = true; options.KeepAliveInterval = TimeSpan.FromSeconds(15); options.ClientTimeoutInterval = TimeSpan.FromSeconds(60); options.MaximumReceiveMessageSize = 32 * 1024; }); services.AddScoped(); services.AddScoped(); // Concrete SignalR push implementation lives here (SL), registered against the // BLL-owned interface — see ICommunicationPushService's doc-comment for why. services.AddScoped(); // Shared, Correspondence-independent document merge engine (GB5Shared/DocumentMerge) — // registered here since Correspondence is its first consumer; a future Sales/CRM // quotation generator would register the same three services in its own module. services.AddScoped(); services.AddScoped(); services.AddScoped(); // Default DI registration for the shared Recording/Transcript/Summary capability (plan: // "New shared capability" — mirrors GB5Shared/DocumentMerge's own registration pattern). // NotConfiguredAICapabilityService always throws — a real provider-backed implementation // is swapped in later via DI without touching any consumer code. services.AddScoped(); // PushNotification cluster lives in GB5Shared (shared by ECPBLL + FrameworkSL) — not // covered by the ECPBLL/ECPDAL scan below, so registered explicitly. services.AddScoped(); services.AddScoped(); // FileUpload cluster lives in GB5Shared (shared by ECPBLL + FrameworkBLL/SL) — not // covered by the ECPBLL/ECPDAL scan below, so registered explicitly. services.AddScoped(); services.AddScoped(); // GB5Shared.ActionProcessor.IEventActionRunDAL/IActionOutboxDAL — needed by CorrespondenceBLL // (Correspondence's action-processor integration). GB5Shared isn't in the ECPBLL/ECPDAL // scan's FromAssemblies list, so these need explicit registration here (mirrors // FrameworkSL/Program.cs's identical registration for the same reason). services.AddScoped(); services.AddScoped(); var ecpBLLAssembly = Assembly.Load("ECPBLL"); var ecpDALAssembly = Assembly.Load("ECPDAL"); // AdminBLL/AdminDAL are deliberately NOT blanket-scanned: they also contain // BulkIceImportBLL/EIPConceptBLL/etc. whose constructors need services this host never // sets up (IFileToDataTableService, ...), which fails DI validation. Communication only // ever needed AdminBLL's SubscriptionBLL (MSUBSCRIPTION routing), so that's registered // narrowly below instead. services.Scan(scan => scan .FromAssemblies(ecpBLLAssembly, ecpDALAssembly) // Canonical filter (mirrors DMSModule.cs's identical scan): // - Exception: every Exception implements ISerializable, so AsImplementedInterfaces() // would otherwise register exception types as services, and DI then fails trying to // activate them via their (string) constructor. // - records (detected via the compiler-generated $ method): a record implicitly // implements IEquatable, so without this, DTOs/records get registered as services // and the container fails trying to activate them via their data constructor. .AddClasses(c => c.Where(t => !t.IsAbstract && !t.IsInterface && !typeof(Exception).IsAssignableFrom(t) && t.GetMethod("$") == null)) .AsImplementedInterfaces() .WithScopedLifetime()); // Narrow cross-module registration for Communication's MSUBSCRIPTION routing (see note // above on why AdminBLL/AdminDAL aren't blanket-scanned). services.AddScoped(); services.AddScoped(); } public void MapEndpoints(WebApplication app) { app.MapHub("/hubs/communication"); } }