using System.Reflection; using adas_core.Domain.Models.AppSettings; using adas_core.Infrastructure.Utils.MongoMaps.Interfaz; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using MongoDB.Bson.Serialization.Conventions; using MongoDB.Driver; using MongoMigrations.Core; using MongoClient = MongoDB.Driver.MongoClient; namespace adas_core.Infrastructure.Utils; /// /// Provides extension methods for configuring MongoDB integration on a host builder. /// public static class MongoDbHostBuilderExtension { /// /// Configures the host builder with the MongoDB conventions and class map registrations required for the application. /// /// The host builder to extend with the MongoDB configuration. /// The same instance, allowing further fluent configuration. public static IHostBuilder UseMongo(this IHostBuilder hostBuilder) { ConfigureMongoDbConventions(); ConfigureRegisterMapClass(); return hostBuilder; } /// /// Runs all pending MongoDB migrations found in the migrations assembly, updating the database schema to the latest version. /// /// The host whose services are used to resolve the instance. /// The same instance, enabling fluent chaining. public static IHost RunMongoMigrations(this IHost host) { using var scope = host.Services.CreateScope(); var database = scope.ServiceProvider.GetRequiredService(); var locator = new MigrationLocator(); locator.LookForMigrationsInAssembly( typeof(adas_core.Infrastructure.Migrations.MongoMigrations.U_0_1_0_UpdateDataPatien).Assembly ); var runner = new MigrationRunner( database, collectionName: "migrations", migrationLocator: locator ); runner.UpdateToLatest(); return host; } /// /// Configures and returns a MongoDB database instance using the provided connection settings. /// Validates that the connection string and database name are provided, and verifies that the database exists. /// /// The database settings containing the MongoDB connection string and database name. /// The configured instance. /// Thrown when the connection string or database name is null or empty. /// Thrown when the specified database does not exist. private static IMongoDatabase ConfigureMongoDbConnection(IOptions dbSettings) { var connectionString = dbSettings.Value.ConnectionString; var databaseName = dbSettings.Value.DatabaseName; if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(databaseName)) throw new Exception("DataBase connection string and name is requiered"); _mongoClient = new MongoClient(connectionString); var mongoDb = _mongoClient.GetDatabase(databaseName); if (mongoDb == null) throw new Exception("DataBase doesn't exist"); return mongoDb; } public static void ConfigureRegisterMapClass() { var assembly = Assembly.GetExecutingAssembly(); // Busca todos los tipos que implementan la interfaz var contributors = assembly.GetTypes() .Where(t => typeof(IEntityMapContributor).IsAssignableFrom(t) && t is { IsInterface: false, IsAbstract: false }); // Crea una instancia de cada contribuidor y ejecuta su método foreach (var contributorType in contributors) { var contributorInstance = (IEntityMapContributor)Activator.CreateInstance(contributorType)!; contributorInstance.RegisterMaps(); } } /// /// Registers global MongoDB serialization conventions, including ignoring extra elements in BSON documents /// and using camelCase for element names, applied to all types in the application. /// public static void ConfigureMongoDbConventions() { var pack = new ConventionPack { new IgnoreExtraElementsConvention(true), new CamelCaseElementNameConvention() }; ConventionRegistry.Register( "Ignore Extra Elements Convention", pack, _ => true); ConventionRegistry.Register( "Camel Case Convention", pack, _ => true); } #region MongoDB private static MongoClient? _mongoClient; #endregion }