Repository: avaje/avaje-inject
Pull request #541 (2024-04-14 09:45:37)

Fix support for @Prototype with Provider<T>
Extracted this fix from #540

@Prototype with Provider<T> currently produces code that registers Provider<Provider<T>> instead of Provider<T> and this fixes that.


Patch:
diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java
index 4855fc3a..d7a4a3ca 100644
--- a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java
+++ b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java
@@ -235,6 +235,8 @@ final class MethodReader {
         writer.append(".asPrimary()");
       } else if (secondary) {
         writer.append(".asSecondary()");
+      } else if (prototype) {
+        writer.append(".asPrototype()");
       }
       if (Util.isProvider(returnTypeRaw)) {
         writer.append(".registerProvider(bean);").eol();
@@ -360,7 +362,7 @@ final class MethodReader {
   }
 
   boolean isProtoType() {
-    return prototype;
+    return prototype && !Util.isProvider(returnTypeRaw);
   }
 
   boolean isLazy() {


Test patch:
diff --git a/inject-test/src/test/java/org/example/coffee/provider/FactoryProvider.java b/inject-test/src/test/java/org/example/coffee/provider/FactoryProvider.java
index 176d6da1..5253c358 100644
--- a/inject-test/src/test/java/org/example/coffee/provider/FactoryProvider.java
+++ b/inject-test/src/test/java/org/example/coffee/provider/FactoryProvider.java
@@ -1,9 +1,11 @@
 package org.example.coffee.provider;
 
+import java.util.Random;
 import java.util.function.Supplier;
 
 import io.avaje.inject.Bean;
 import io.avaje.inject.Factory;
+import io.avaje.inject.Prototype;
 import io.avaje.inject.Secondary;
 import jakarta.inject.Named;
 import jakarta.inject.Provider;
@@ -22,4 +24,10 @@ public class FactoryProvider {
   Provider<Supplier<String>> supply() {
     return () -> () -> "Stand proud Provider, you were strong";
   }
+
+  @Bean
+  @Prototype
+  Provider<Long> random() {
+    return new Random()::nextLong;
+  }
 }
diff --git a/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java b/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java
index b1868a14..5b2e6e74 100644
--- a/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java
+++ b/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java
@@ -19,4 +19,12 @@ class FactoryProviderTest {
       assertThat(scope.get(String.class, "second")).isEqualTo("Nah, I'd win");
     }
   }
+
+  @Test
+  void testProtoType() {
+    try (var scope = BeanScope.builder().build()) {
+      var numberGetter = scope.get(ProtoTypeNumberGetter.class);
+      assertThat(numberGetter.number()).isNotEqualTo(numberGetter.number());
+    }
+  }
 }
diff --git a/inject-test/src/test/java/org/example/coffee/provider/ProtoTypeNumberGetter.java b/inject-test/src/test/java/org/example/coffee/provider/ProtoTypeNumberGetter.java
new file mode 100644
index 00000000..358d7d7a
--- /dev/null
+++ b/inject-test/src/test/java/org/example/coffee/provider/ProtoTypeNumberGetter.java
@@ -0,0 +1,18 @@
+package org.example.coffee.provider;
+
+import jakarta.inject.Provider;
+import jakarta.inject.Singleton;
+
+@Singleton
+class ProtoTypeNumberGetter {
+
+  private final Provider<Long> nProv;
+
+  ProtoTypeNumberGetter(Provider<Long> nProv) {
+    this.nProv = nProv;
+  }
+
+  Long number() {
+    return nProv.get();
+  }
+}