Skip to content

Commit 8aacee1

Browse files
committed
#94 - Compile error when field injecting Provider<T>
1 parent b0f64fa commit 8aacee1

File tree

8 files changed

+120
-2
lines changed

8 files changed

+120
-2
lines changed

inject-generator/src/main/java/io/avaje/inject/generator/FieldReader.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,18 @@ String getFieldName() {
2323
String builderGetDependency() {
2424
StringBuilder sb = new StringBuilder();
2525
sb.append("b.").append(type.getMethod());
26-
sb.append(type.rawType()).append(".class");
26+
sb.append(getFieldType()).append(".class");
2727
if (name != null) {
2828
sb.append(",\"").append(name).append("\"");
2929
}
3030
sb.append(")");
3131
return sb.toString();
3232
}
3333

34+
private String getFieldType() {
35+
return Util.unwrapProvider(type.rawType());
36+
}
37+
3438
/**
3539
* Check for request scoped dependency.
3640
*/
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.example.coffee.provider;
2+
3+
import javax.inject.Inject;
4+
import javax.inject.Provider;
5+
import javax.inject.Singleton;
6+
7+
@Singleton
8+
class FieldInjectProvider {
9+
10+
@Inject
11+
Provider<AProv> aProvProvider;
12+
13+
AProv testGet() {
14+
return aProvProvider.get();
15+
}
16+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.example.coffee.provider;
2+
3+
import io.avaje.inject.SystemContext;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static org.assertj.core.api.Assertions.assertThat;
7+
8+
class FieldInjectProviderTest {
9+
10+
@Test
11+
void test() {
12+
13+
FieldInjectProvider bean = SystemContext.getBean(FieldInjectProvider.class);
14+
AProv aProv = bean.testGet();
15+
16+
assertThat(aProv).isNotNull();
17+
18+
AProv beanDirect = SystemContext.getBean(AProv.class);
19+
assertThat(aProv).isSameAs(beanDirect);
20+
}
21+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.example.missing;
2+
3+
import javax.inject.Singleton;
4+
5+
/**
6+
* Has only 1 public constructor so that is chosen for injection.
7+
*/
8+
@Singleton
9+
public class MFooUser2 {
10+
11+
private final MFoo mf;
12+
private final boolean usePublicConstructor;
13+
14+
public MFooUser2(MFoo mf) {
15+
this.mf = mf;
16+
this.usePublicConstructor = true;
17+
}
18+
19+
/**
20+
* Extra protected constructor usually for unit testing purposes only.
21+
*/
22+
MFooUser2(MFoo mf, boolean dummy) {
23+
this.mf = mf;
24+
this.usePublicConstructor = true;
25+
}
26+
27+
public boolean isUsePublicConstructor() {
28+
return usePublicConstructor;
29+
}
30+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.example.missing;
2+
3+
import io.avaje.inject.SystemContext;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static org.assertj.core.api.Assertions.assertThat;
7+
8+
class SinglePublicConstructorTest {
9+
10+
@Test
11+
void beanWithSinglePublicConstructor_expect_publicConstructorChosen() {
12+
13+
MFooUser2 bean = SystemContext.getBean(MFooUser2.class);
14+
15+
assertThat(bean.isUsePublicConstructor()).isTrue();
16+
}
17+
}

inject/src/main/java/io/avaje/inject/spi/DBuilder.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ class DBuilder implements Builder {
5656
*/
5757
private Class<?> injectTarget;
5858

59+
/**
60+
* Flag set when we are running post construct injection.
61+
*/
62+
private boolean runningPostConstruct;
63+
5964
Builder parent;
6065

6166
/**
@@ -224,6 +229,9 @@ public <T> Provider<T> getProvider(Class<T> cls) {
224229

225230
@Override
226231
public <T> Provider<T> getProvider(Class<T> cls, String name) {
232+
if (runningPostConstruct) {
233+
return new ProviderWrapper<>(get(cls, name));
234+
}
227235
ProviderPromise<T> promise = new ProviderPromise<>(cls, name);
228236
injectors.add(promise);
229237
return promise;
@@ -256,6 +264,7 @@ private void runInjectors() {
256264
if (name != null) {
257265
log.debug("perform field injection in context:{}", name);
258266
}
267+
runningPostConstruct = true;
259268
for (Consumer<Builder> injector : injectors) {
260269
injector.accept(this);
261270
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.avaje.inject.spi;
2+
3+
import javax.inject.Provider;
4+
5+
/**
6+
* Just wrap a bean.
7+
*/
8+
class ProviderWrapper<T> implements Provider<T> {
9+
10+
private T bean;
11+
12+
ProviderWrapper(T bean) {
13+
this.bean = bean;
14+
}
15+
16+
@Override
17+
public T get() {
18+
return bean;
19+
}
20+
21+
}

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<modules>
2727
<module>inject</module>
2828
<module>inject-generator</module>
29-
<!-- <module>inject-test</module>-->
29+
<module>inject-test</module>
3030
</modules>
3131
</project>
3232

0 commit comments

Comments
 (0)