Procházet zdrojové kódy

fix(mapping): keep PropertyMapper target alive after builder disposal

clanker před 1 týdnem
rodič
revize
9992e252d0
1 změnil soubory, kde provedl 8 přidání a 4 odebrání
  1. 8 4
      src/lib/Mapping/PropertyMapper.vala

+ 8 - 4
src/lib/Mapping/PropertyMapper.vala

@@ -11,7 +11,7 @@ namespace Invercargill.Mapping {
     public class PropertyMapper<T> : Object, Mapper<T, Properties> {
 
         private Vector<PropertyMapping<T>> mappings;
-        private ObjectConstructor<T> constructor;
+        private ObjectConstructor<T>? constructor;
 
         public static PropertyMapper<T> build_for<T>(Func<PropertyMapperBuilder<T>> func) {
             int location = (int)func;
@@ -22,7 +22,7 @@ namespace Invercargill.Mapping {
             });
         }
 
-        internal PropertyMapper(Vector<PropertyMapping<T>> mappings, ObjectConstructor<T> constructor) {
+        internal PropertyMapper(Vector<PropertyMapping<T>> mappings, ObjectConstructor<T>? constructor) {
             this.mappings = mappings;
             this.constructor = constructor;
         }
@@ -50,7 +50,7 @@ namespace Invercargill.Mapping {
         }
 
         public T materialise(Properties properties) throws Error {
-            var obj = constructor();
+            var obj = constructor != null ? constructor() : (T) Object.new(typeof(T));
             map_into(obj, properties);
             return obj;
         }
@@ -95,7 +95,11 @@ namespace Invercargill.Mapping {
 
         public PropertyMapperBuilder() {
             mappings = new Vector<PropertyMapping<T>>();
-            constructor = () => Object.new(typeof(T));
+            // No default constructor closure: a lambda capturing `this` would
+            // dangle once the (usually transient) builder is finalized while
+            // the built PropertyMapper lives on. materialise() falls back to
+            // the mapper's own T when no constructor was set.
+            constructor = null;
         }
 
         public virtual PropertyMappingBuilder<T> map<TProp>(string name, owned PropertyGetter<T, TProp> getter, owned PropertySetter<T, TProp> setter) {