| | | 1 | | using Chronicis.Client.Abstractions; |
| | | 2 | | using Chronicis.Client.Infrastructure; |
| | | 3 | | using Chronicis.Client.Services; |
| | | 4 | | using Chronicis.Client.ViewModels; |
| | | 5 | | using Chronicis.Shared.Admin; |
| | | 6 | | using Microsoft.Extensions.Options; |
| | | 7 | | |
| | | 8 | | namespace Chronicis.Client.Extensions; |
| | | 9 | | |
| | | 10 | | /// <summary> |
| | | 11 | | /// Extension methods for registering application services. |
| | | 12 | | /// </summary> |
| | | 13 | | public static class ApplicationServiceExtensions |
| | | 14 | | { |
| | | 15 | | /// <summary> |
| | | 16 | | /// Adds all Chronicis application services including API services, |
| | | 17 | | /// state services, and domain services. |
| | | 18 | | /// </summary> |
| | | 19 | | public static IServiceCollection AddChronicisApplicationServices( |
| | | 20 | | this IServiceCollection services, |
| | | 21 | | IConfiguration configuration) |
| | | 22 | | { |
| | | 23 | | // SysAdmin checker — reads from the "SysAdmin" config section in wwwroot/appsettings.json |
| | 1 | 24 | | services.Configure<SysAdminOptions>(configuration.GetSection("SysAdmin")); |
| | 1 | 25 | | services.AddSingleton<ISysAdminChecker>(sp => |
| | 1 | 26 | | { |
| | 1 | 27 | | var options = sp.GetRequiredService<IOptions<SysAdminOptions>>().Value; |
| | 1 | 28 | | return new SysAdminChecker(options); |
| | 1 | 29 | | }); |
| | | 30 | | |
| | | 31 | | // API Services - use the authenticated "ChronicisApi" client |
| | 1 | 32 | | services.AddChronicisApiService<IArticleApiService, ArticleApiService>(); |
| | 1 | 33 | | services.AddChronicisApiService<ISearchApiService, SearchApiService>(); |
| | 1 | 34 | | services.AddChronicisApiService<IAISummaryApiService, AISummaryApiService>(); |
| | 1 | 35 | | services.AddChronicisApiService<IWorldApiService, WorldApiService>(); |
| | 1 | 36 | | services.AddChronicisApiService<ICampaignApiService, CampaignApiService>(); |
| | 1 | 37 | | services.AddChronicisApiService<IArcApiService, ArcApiService>(); |
| | 1 | 38 | | services.AddChronicisApiService<ISessionApiService, SessionApiService>(); |
| | 1 | 39 | | services.AddChronicisApiService<ILinkApiService, LinkApiService>(); |
| | 1 | 40 | | services.AddChronicisApiService<IArticleExternalLinkApiService, ArticleExternalLinkApiService>(); |
| | 1 | 41 | | services.AddChronicisApiService<IExternalLinkApiService, ExternalLinkApiService>(); |
| | 1 | 42 | | services.AddChronicisApiService<IUserApiService, UserApiService>(); |
| | 1 | 43 | | services.AddChronicisApiService<ICharacterApiService, CharacterApiService>(); |
| | 1 | 44 | | services.AddChronicisApiService<IDashboardApiService, DashboardApiService>(); |
| | 1 | 45 | | services.AddChronicisApiService<IResourceProviderApiService, ResourceProviderApiService>(); |
| | 1 | 46 | | services.AddChronicisApiService<IAdminApiService, AdminApiService>(); |
| | 1 | 47 | | services.AddChronicisApiService<ITutorialApiService, TutorialApiService>(); |
| | 1 | 48 | | services.AddChronicisApiService<IMapApiService, MapApiService>(); |
| | | 49 | | |
| | | 50 | | // API services with special dependencies |
| | 1 | 51 | | services.AddChronicisApiServiceWithSnackbar<IQuestApiService, QuestApiService>(); |
| | 1 | 52 | | services.AddChronicisApiServiceWithJSRuntime<IExportApiService, ExportApiService>(); |
| | | 53 | | |
| | | 54 | | // Public API service (uses unauthenticated client) |
| | 1 | 55 | | services.AddScoped<IPublicApiService>(sp => |
| | 1 | 56 | | { |
| | 1 | 57 | | var factory = sp.GetRequiredService<IHttpClientFactory>(); |
| | 1 | 58 | | var logger = sp.GetRequiredService<ILogger<PublicApiService>>(); |
| | 1 | 59 | | return new PublicApiService(factory.CreateClient("ChronicisPublicApi"), logger); |
| | 1 | 60 | | }); |
| | | 61 | | |
| | | 62 | | // Health Status API service (uses unauthenticated client since health endpoints are public) |
| | 1 | 63 | | services.AddScoped<IHealthStatusApiService>(sp => |
| | 1 | 64 | | { |
| | 1 | 65 | | var factory = sp.GetRequiredService<IHttpClientFactory>(); |
| | 1 | 66 | | var logger = sp.GetRequiredService<ILogger<HealthStatusApiService>>(); |
| | 1 | 67 | | return new HealthStatusApiService(factory.CreateClient("ChronicisPublicApi"), logger); |
| | 1 | 68 | | }); |
| | | 69 | | |
| | | 70 | | // UI Infrastructure abstractions — decouple ViewModels from MudBlazor/JS/NavigationManager |
| | 1 | 71 | | services.AddScoped<IAppNavigator, AppNavigator>(); |
| | 1 | 72 | | services.AddScoped<IUserNotifier, UserNotifier>(); |
| | 1 | 73 | | services.AddScoped<IConfirmationService, ConfirmationService>(); |
| | 1 | 74 | | services.AddScoped<IPageTitleService, PageTitleService>(); |
| | | 75 | | |
| | | 76 | | // ViewModels |
| | 1 | 77 | | services.AddTransient<SearchViewModel>(); |
| | 1 | 78 | | services.AddTransient<DashboardViewModel>(); |
| | 1 | 79 | | services.AddTransient<CampaignDetailViewModel>(); |
| | 1 | 80 | | services.AddTransient<ArcDetailViewModel>(); |
| | 1 | 81 | | services.AddTransient<SessionDetailViewModel>(); |
| | 1 | 82 | | services.AddTransient<WorldDetailViewModel>(); |
| | 1 | 83 | | services.AddTransient<WorldLinksViewModel>(); |
| | 1 | 84 | | services.AddTransient<WorldDocumentsViewModel>(); |
| | 1 | 85 | | services.AddTransient<WorldSharingViewModel>(); |
| | 1 | 86 | | services.AddTransient<ArticleDetailViewModel>(); |
| | 1 | 87 | | services.AddTransient<CosmosViewModel>(); |
| | 1 | 88 | | services.AddTransient<GettingStartedViewModel>(); |
| | 1 | 89 | | services.AddTransient<PublicWorldPageViewModel>(); |
| | | 90 | | |
| | | 91 | | // State & coordination services |
| | 1 | 92 | | services.AddScoped<ITreeStateService, TreeStateService>(); |
| | 1 | 93 | | services.AddScoped<IAuthService, AuthService>(); |
| | 1 | 94 | | services.AddScoped<IAdminAuthService, AdminAuthService>(); |
| | 1 | 95 | | services.AddScoped<IAppContextService, AppContextService>(); |
| | 1 | 96 | | services.AddScoped<IDrawerCoordinator, DrawerCoordinator>(); |
| | 1 | 97 | | services.AddScoped<IMetadataDrawerService, MetadataDrawerService>(); |
| | 1 | 98 | | services.AddScoped<IQuestDrawerService, QuestDrawerService>(); |
| | 1 | 99 | | services.AddScoped<IKeyboardShortcutService, KeyboardShortcutService>(); |
| | 1 | 100 | | services.AddScoped<TutorialPageTypeResolver>(); |
| | | 101 | | |
| | | 102 | | // Domain services |
| | 1 | 103 | | services.AddScoped<IArticleCacheService, ArticleCacheService>(); |
| | 1 | 104 | | services.AddScoped<IWikiLinkService, WikiLinkService>(); |
| | 1 | 105 | | services.AddScoped<IWikiLinkAutocompleteService, WikiLinkAutocompleteService>(); |
| | 1 | 106 | | services.AddScoped<IBreadcrumbService, BreadcrumbService>(); |
| | 1 | 107 | | services.AddScoped<IMarkdownService, MarkdownService>(); |
| | | 108 | | |
| | | 109 | | // Render definition service (loads from wwwroot static assets via base URI) |
| | 1 | 110 | | services.AddScoped<IRenderDefinitionService>(sp => |
| | 1 | 111 | | { |
| | 1 | 112 | | var navigationManager = sp.GetRequiredService<Microsoft.AspNetCore.Components.NavigationManager>(); |
| | 1 | 113 | | var http = new HttpClient { BaseAddress = new Uri(navigationManager.BaseUri) }; |
| | 1 | 114 | | var logger = sp.GetRequiredService<ILogger<RenderDefinitionService>>(); |
| | 1 | 115 | | return new RenderDefinitionService(http, logger); |
| | 1 | 116 | | }); |
| | | 117 | | |
| | | 118 | | // Version service — reads wwwroot/version.json stamped by CI |
| | 1 | 119 | | services.AddSingleton<IVersionService>(sp => |
| | 1 | 120 | | { |
| | 1 | 121 | | var navigationManager = sp.GetRequiredService<Microsoft.AspNetCore.Components.NavigationManager>(); |
| | 1 | 122 | | var http = new HttpClient { BaseAddress = new Uri(navigationManager.BaseUri) }; |
| | 1 | 123 | | var logger = sp.GetRequiredService<ILogger<VersionService>>(); |
| | 1 | 124 | | return new VersionService(http, logger); |
| | 1 | 125 | | }); |
| | | 126 | | |
| | 1 | 127 | | return services; |
| | | 128 | | } |
| | | 129 | | } |