Parcourir la source

refactor(di): add metadata to type registrations and adjust lifecycles

- Add MapperTypeInfo metadata to mapper and projection registrations
  for improved type resolution via get_metadata lookups
- Change InversionTypeProvider from singleton to transient lifecycle
- Refactor MigrationStartupService to create its own scope internally
  instead of receiving it as a constructor parameter
- Add debug print statements for type resolution troubleshooting
Billy Barrow il y a 1 mois
Parent
commit
a0f8ad71b5

+ 6 - 3
src/DatabaseConfigurator.vala

@@ -22,6 +22,7 @@ namespace InvercargillSqlInversion {
 
             // Register the connection 
             container.register<Connection>(() => ConnectionFactory.create_and_open(connection_string), effective_lifecycle);
+            print(@"Registered as $effective_lifecycle\n");
 
             // Register the dialect provider
             container.register_transient<SqlDialect>(() => DialectFactory.create_from_string(connection_string));
@@ -30,7 +31,7 @@ namespace InvercargillSqlInversion {
             container.register_transient<MigrationRunner>(s => new MigrationRunner(s.resolve<Connection>(), s.resolve<SqlDialect>()));
 
             // Register the type registry
-            container.register_singleton<InversionTypeProvider>()
+            container.register_transient<InversionTypeProvider>()
                 .as<TypeProvider>();
 
             // Register the orm session
@@ -51,7 +52,8 @@ namespace InvercargillSqlInversion {
                 configuration_func(builder);
                 var schema = dialect.introspect_schema(connection, builder.peek_table());
                 return builder.build_with_schema(schema);
-            });
+            })
+            .with_metadata<MapperTypeInfo>(new MapperTypeInfo(typeof(T)));
         }
         
         public void add_projection<T>(owned ProjectionFactoryFunc<T> configuration_func) throws Error {
@@ -60,7 +62,8 @@ namespace InvercargillSqlInversion {
                 var builder = new ProjectionBuilder<T>(type_provider);
                 configuration_func(builder);
                 return builder.build();
-            });
+            })
+            .with_metadata<MapperTypeInfo>(new MapperTypeInfo(typeof(T)));
         }
         
         public void migrate_on_startup() {

+ 4 - 0
src/InversionTypeProvider.vala

@@ -8,6 +8,7 @@ namespace InvercargillSqlInversion {
         private Scope scope = inject<Scope>();
 
         public InvercargillSql.Orm.EntityMapper? get_mapper_for_type (GLib.Type type) throws Error {
+            print(@"get_mapper_for_type $(type.name())\n");
             var reg = scope.get_registrations(typeof(EntityMapper))
                 .where(r => r.get_metadata<MapperTypeInfo>().any(i => i.mapper_type == type))
                 .first_or_default();
@@ -19,6 +20,7 @@ namespace InvercargillSqlInversion {
         }
 
         public InvercargillSql.Orm.Projections.ProjectionDefinition? get_projection_for_type (GLib.Type type) throws Error {
+            print(@"get_projection_for_type $(type.name())\n");
             var reg = scope.get_registrations(typeof(Projections.ProjectionDefinition))
                 .where(r => r.get_metadata<MapperTypeInfo>().any(i => i.mapper_type == type))
                 .first_or_default();
@@ -29,10 +31,12 @@ namespace InvercargillSqlInversion {
             return (Projections.ProjectionDefinition)scope.resolve_registration(reg);
         }
         public bool has_mapper_for_type (GLib.Type type) {
+            print(@"has_mapper_for_type $(type.name())\n");
             return scope.get_registrations(typeof(EntityMapper))
                 .any(r => r.get_metadata<MapperTypeInfo>().any(i => i.mapper_type == type));
         }
         public bool has_projection_for_type (GLib.Type type) {
+            print(@"has_projection_for_type $(type.name())\n");
             return scope.get_registrations(typeof(Projections.ProjectionDefinition))
                 .any(r => r.get_metadata<MapperTypeInfo>().any(i => i.mapper_type == type));
         }

+ 18 - 10
src/MigrationStartupService.vala

@@ -9,23 +9,31 @@ namespace InvercargillSqlInversion {
     /// instantiated when container.initialise() is called.
     /// </summary>
     public class MigrationStartupService : Object {
+
+        private Container container = inject<Container>();
         
         /// <summary>
         /// Creates a new MigrationStartupService and runs pending migrations.
         /// </summary>
         /// <param name="scope">The resolution scope used to resolve the MigrationRunner and migrations.</param>
         /// <throws>Error">If migration fails or dependencies cannot be resolved.</throws>
-        public MigrationStartupService(Scope scope) throws Error {
-            var runner = scope.resolve<MigrationRunner>();
-            
-            // Get all registered migrations and register them with the runner
-            var migrations = scope.resolve_all<Migration>();
-            foreach (var migration in migrations) {
-                runner.register_migration(migration);
+        construct {
+            try {
+                var scope = container.create_scope ();
+                var runner = scope.resolve<MigrationRunner>();
+                
+                // Get all registered migrations and register them with the runner
+                var migrations = scope.resolve_all<Migration>();
+                foreach (var migration in migrations) {
+                    runner.register_migration(migration);
+                }
+                
+                // Execute migrations to the latest version
+                runner.migrate_to_latest();
+            }
+            catch(Error e) {
+                error("Migration runner error: " + e.message);
             }
-            
-            // Execute migrations to the latest version
-            runner.migrate_to_latest();
         }
     }
 }