< Summary

Information
Class: FirebaseAdapter.ServiceCollectionExtensions
Assembly: FirebaseAdapter
File(s): /home/runner/work/KicktippAi/KicktippAi/src/FirebaseAdapter/ServiceCollectionExtensions.cs
Line coverage
59%
Covered lines: 51
Uncovered lines: 35
Coverable lines: 86
Total lines: 172
Line coverage: 59.3%
Branch coverage
85%
Covered branches: 12
Total branches: 14
Branch coverage: 85.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddFirebaseDatabase(...)100%1212100%
AddFirebaseDatabase(...)100%11100%
AddFirebaseDatabase(...)100%11100%
AddFirebaseDatabaseWithFile(...)100%11100%

File(s)

/home/runner/work/KicktippAi/KicktippAi/src/FirebaseAdapter/ServiceCollectionExtensions.cs

#LineLine coverage
 1using FirebaseAdapter.Configuration;
 2using Google.Cloud.Firestore;
 3using Microsoft.Extensions.DependencyInjection;
 4using Microsoft.Extensions.Logging;
 5using Microsoft.Extensions.Options;
 6using Microsoft.Extensions.Configuration;
 7using System.Text;
 8using EHonda.KicktippAi.Core;
 9
 10namespace FirebaseAdapter;
 11
 12/// <summary>
 13/// Extension methods for configuring Firebase services in dependency injection.
 14/// </summary>
 15public static class ServiceCollectionExtensions
 16{
 17    /// <summary>
 18    /// Adds Firebase Firestore database services to the service collection.
 19    /// </summary>
 20    /// <param name="services">The service collection to add services to.</param>
 21    /// <param name="configureOptions">Optional configuration delegate for Firebase options.</param>
 22    /// <param name="community">The community identifier for collection naming.</param>
 23    /// <returns>The service collection for chaining.</returns>
 24    public static IServiceCollection AddFirebaseDatabase(
 25        this IServiceCollection services,
 26        Action<FirebaseOptions>? configureOptions = null,
 27        string? community = null)
 28    {
 29        // Configure options
 130        if (configureOptions != null)
 31        {
 132            services.Configure(configureOptions);
 33        }
 34
 35        // Register FirestoreDb as a singleton
 136        services.AddSingleton<FirestoreDb>(serviceProvider =>
 137        {
 038            var options = serviceProvider.GetRequiredService<IOptions<FirebaseOptions>>().Value;
 039            var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
 040            var logger = loggerFactory.CreateLogger("FirebaseAdapter.ServiceCollectionExtensions");
 141
 142            try
 143            {
 044                options.Validate();
 145
 146                FirestoreDb firestoreDb;
 147
 048                if (!string.IsNullOrWhiteSpace(options.ServiceAccountPath))
 149                {
 150                    // Use service account file path
 051                    logger.LogInformation("Initializing Firebase with service account file: {Path}", options.ServiceAcco
 152
 053                    Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", options.ServiceAccountPath);
 054                    firestoreDb = FirestoreDb.Create(options.ProjectId);
 155                }
 156                else
 157                {
 158                    // Use service account JSON content
 059                    logger.LogInformation("Initializing Firebase with service account JSON content for project: {Project
 160
 161                    // Create FirestoreDb from JSON content
 062                    var credentialsBytes = Encoding.UTF8.GetBytes(options.ServiceAccountJson);
 063                    using var stream = new MemoryStream(credentialsBytes);
 164
 065                    var firestoreDbBuilder = new FirestoreDbBuilder
 066                    {
 067                        ProjectId = options.ProjectId,
 068                        JsonCredentials = options.ServiceAccountJson
 069                    };
 170
 071                    firestoreDb = firestoreDbBuilder.Build();
 172                }
 173
 074                logger.LogInformation("Firebase Firestore successfully initialized for project: {ProjectId}", options.Pr
 075                return firestoreDb;
 176            }
 077            catch (Exception ex)
 178            {
 079                logger.LogError(ex, "Failed to initialize Firebase Firestore for project: {ProjectId}", options.ProjectI
 080                throw;
 181            }
 082        });
 83
 84        // Register the prediction repository
 185        services.AddScoped<IPredictionRepository>(serviceProvider =>
 186        {
 087            var firestoreDb = serviceProvider.GetRequiredService<FirestoreDb>();
 088            var logger = serviceProvider.GetRequiredService<ILogger<FirebasePredictionRepository>>();
 089            return new FirebasePredictionRepository(firestoreDb, logger);
 190        });
 91
 92        // Register the KPI repository
 193        services.AddScoped<IKpiRepository>(serviceProvider =>
 194        {
 095            var firestoreDb = serviceProvider.GetRequiredService<FirestoreDb>();
 096            var logger = serviceProvider.GetRequiredService<ILogger<FirebaseKpiRepository>>();
 097            return new FirebaseKpiRepository(firestoreDb, logger);
 198        });
 99
 100        // Register the context repository
 1101        services.AddScoped<IContextRepository>(serviceProvider =>
 1102        {
 0103            var firestoreDb = serviceProvider.GetRequiredService<FirestoreDb>();
 0104            var logger = serviceProvider.GetRequiredService<ILogger<FirebaseContextRepository>>();
 0105            return new FirebaseContextRepository(firestoreDb, logger);
 1106        });
 107
 108        // Register the KPI context provider
 1109        services.AddScoped<FirebaseKpiContextProvider>(serviceProvider =>
 1110        {
 0111            var kpiRepository = serviceProvider.GetRequiredService<IKpiRepository>();
 0112            var logger = serviceProvider.GetRequiredService<ILogger<FirebaseKpiContextProvider>>();
 0113            return new FirebaseKpiContextProvider(kpiRepository, logger);
 1114        });
 115
 1116        return services;
 117    }
 118
 119    /// <summary>
 120    /// Adds Firebase Firestore database services with configuration from IConfiguration.
 121    /// </summary>
 122    /// <param name="services">The service collection to add services to.</param>
 123    /// <param name="configuration">The configuration to bind Firebase options from.</param>
 124    /// <returns>The service collection for chaining.</returns>
 125    public static IServiceCollection AddFirebaseDatabase(
 126        this IServiceCollection services,
 127        IConfiguration configuration)
 128    {
 1129        services.Configure<FirebaseOptions>(configuration.GetSection(FirebaseOptions.SectionName));
 1130        return services.AddFirebaseDatabase((Action<FirebaseOptions>?)null);
 131    }
 132
 133    /// <summary>
 134    /// Adds Firebase Firestore database services with explicit project ID and service account JSON.
 135    /// </summary>
 136    /// <param name="services">The service collection to add services to.</param>
 137    /// <param name="projectId">Firebase project ID.</param>
 138    /// <param name="serviceAccountJson">Service account JSON content.</param>
 139    /// <param name="community">The community identifier for collection naming.</param>
 140    /// <returns>The service collection for chaining.</returns>
 141    public static IServiceCollection AddFirebaseDatabase(
 142        this IServiceCollection services,
 143        string projectId,
 144        string serviceAccountJson,
 145        string community)
 146    {
 1147        return services.AddFirebaseDatabase(options =>
 1148        {
 1149            options.ProjectId = projectId;
 1150            options.ServiceAccountJson = serviceAccountJson;
 1151        }, community);
 152    }
 153
 154    /// <summary>
 155    /// Adds Firebase Firestore database services with explicit project ID and service account file path.
 156    /// </summary>
 157    /// <param name="services">The service collection to add services to.</param>
 158    /// <param name="projectId">Firebase project ID.</param>
 159    /// <param name="serviceAccountPath">Path to service account JSON file.</param>
 160    /// <returns>The service collection for chaining.</returns>
 161    public static IServiceCollection AddFirebaseDatabaseWithFile(
 162        this IServiceCollection services,
 163        string projectId,
 164        string serviceAccountPath)
 165    {
 1166        return services.AddFirebaseDatabase(options =>
 1167        {
 1168            options.ProjectId = projectId;
 1169            options.ServiceAccountPath = serviceAccountPath;
 1170        });
 171    }
 172}