Skip to content

Commit 6390f0b

Browse files
committed
add Guice bind* functions #368
1 parent f2ff412 commit 6390f0b

File tree

2 files changed

+236
-4
lines changed

2 files changed

+236
-4
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package org.jooby.issues;
2+
3+
import org.jooby.test.ServerFeature;
4+
import org.junit.Test;
5+
6+
import com.typesafe.config.ConfigFactory;
7+
import com.typesafe.config.ConfigValueFactory;
8+
9+
public class Issue368 extends ServerFeature {
10+
11+
public interface S {
12+
String doSomething();
13+
}
14+
15+
public interface Sx {
16+
String doSomething();
17+
}
18+
19+
public static class S1 implements S {
20+
21+
@Override
22+
public String doSomething() {
23+
return "s1";
24+
}
25+
26+
}
27+
28+
public static class S12 implements S {
29+
private String v;
30+
31+
public S12(final String v) {
32+
this.v = v;
33+
}
34+
35+
@Override
36+
public String doSomething() {
37+
return v;
38+
}
39+
40+
}
41+
42+
public static class Sx12 implements Sx {
43+
private String v;
44+
45+
public Sx12(final String v) {
46+
this.v = v;
47+
}
48+
49+
@Override
50+
public String doSomething() {
51+
return v;
52+
}
53+
54+
}
55+
56+
public static class S2 {
57+
58+
public String doSomething() {
59+
return "s2";
60+
}
61+
62+
}
63+
64+
public static class S3 {
65+
66+
public String doSomething() {
67+
return "s3";
68+
}
69+
70+
}
71+
72+
public static class S4 implements S {
73+
74+
@Override
75+
public String doSomething() {
76+
return "s4";
77+
}
78+
79+
}
80+
81+
{
82+
use(ConfigFactory.empty().withValue("v", ConfigValueFactory.fromAnyRef("s12")));
83+
84+
bind(S2.class);
85+
bind(c -> new S12(c.getString("v")));
86+
bind(new S3());
87+
bind(S.class, S1.class);
88+
bind(Sx.class, c -> new Sx12(c.getString("v")));
89+
bind(S4.class, S4::new);
90+
91+
get("/bind", req -> {
92+
return req.require(S2.class).doSomething()
93+
+ ";" + req.require(S12.class).doSomething()
94+
+ ";" + req.require(S3.class).doSomething()
95+
+ ";" + req.require(S.class).doSomething()
96+
+ ";" + req.require(Sx.class).doSomething()
97+
+ ";" + req.require(S4.class).doSomething();
98+
});
99+
}
100+
101+
@Test
102+
public void shouldSimplifyBinding() throws Exception {
103+
request()
104+
.get("/bind")
105+
.expect("s2;s12;s3;s1;s12;s4");
106+
}
107+
108+
}

jooby/src/main/java/org/jooby/Jooby.java

Lines changed: 128 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ public EnvDep(final Predicate<String> predicate, final Consumer<Config> callback
585585
/** stop callback . */
586586
private List<CheckedConsumer<Registry>> onStop = new ArrayList<>();
587587

588-
/** Mappers .*/
588+
/** Mappers . */
589589
@SuppressWarnings("rawtypes")
590590
private Mapper mapper;
591591

@@ -3039,9 +3039,9 @@ public Route.Definition assets(final String path, final String location) {
30393039
AssetHandler handler = new AssetHandler(location);
30403040
on("*", conf -> {
30413041
handler
3042-
.cdn(conf.getString("assets.cdn"))
3043-
.lastModified(conf.getBoolean("assets.lastModified"))
3044-
.etag(conf.getBoolean("assets.etag"));
3042+
.cdn(conf.getString("assets.cdn"))
3043+
.lastModified(conf.getBoolean("assets.lastModified"))
3044+
.etag(conf.getBoolean("assets.etag"));
30453045
});
30463046
return assets(path, handler);
30473047
}
@@ -3458,6 +3458,130 @@ public Jooby mapper(final Mapper mapper) {
34583458
return this;
34593459
}
34603460

3461+
/**
3462+
* Bind the provided abstract type to the given implementation:
3463+
*
3464+
* <pre>
3465+
* {
3466+
* bind(MyInterface.class, MyImplementation.class);
3467+
* }
3468+
* </pre>
3469+
*
3470+
* @param type Service interface.
3471+
* @param implementation Service implementation.
3472+
* @return This instance.
3473+
*/
3474+
public <T> Jooby bind(final Class<T> type, final Class<? extends T> implementation) {
3475+
use((env, conf, binder) -> {
3476+
binder.bind(type).to(implementation);
3477+
});
3478+
return this;
3479+
}
3480+
3481+
/**
3482+
* Bind the provided abstract type to the given implementation:
3483+
*
3484+
* <pre>
3485+
* {
3486+
* bind(MyInterface.class, MyImplementation::new);
3487+
* }
3488+
* </pre>
3489+
*
3490+
* @param type Service interface.
3491+
* @param implementation Service implementation.
3492+
* @return This instance.
3493+
*/
3494+
public <T> Jooby bind(final Class<T> type, final Supplier<T> implementation) {
3495+
use((env, conf, binder) -> {
3496+
binder.bind(type).toInstance(implementation.get());
3497+
});
3498+
return this;
3499+
}
3500+
3501+
/**
3502+
* Bind the provided type:
3503+
*
3504+
* <pre>
3505+
* {
3506+
* bind(MyInterface.class);
3507+
* }
3508+
* </pre>
3509+
*
3510+
* @param type Service interface.
3511+
* @return This instance.
3512+
*/
3513+
public <T> Jooby bind(final Class<T> type) {
3514+
use((env, conf, binder) -> {
3515+
binder.bind(type);
3516+
});
3517+
return this;
3518+
}
3519+
3520+
/**
3521+
* Bind the provided type:
3522+
*
3523+
* <pre>
3524+
* {
3525+
* bind(new MyService());
3526+
* }
3527+
* </pre>
3528+
*
3529+
* @param service Service.
3530+
* @return This instance.
3531+
*/
3532+
@SuppressWarnings({"rawtypes", "unchecked" })
3533+
public <T> Jooby bind(final Object service) {
3534+
use((env, conf, binder) -> {
3535+
Class type = service.getClass();
3536+
binder.bind(type).toInstance(service);
3537+
});
3538+
return this;
3539+
}
3540+
3541+
/**
3542+
* Bind the provided type and object that requires some type of configuration:
3543+
*
3544+
* <pre>{@code
3545+
* {
3546+
* bind(MyService.class, conf -> new MyService(conf.getString("service.url")));
3547+
* }
3548+
* }</pre>
3549+
*
3550+
* @param type Service type.
3551+
* @param provider Service provider.
3552+
* @return This instance.
3553+
*/
3554+
public <T> Jooby bind(final Class<T> type, final Function<Config, ? extends T> provider) {
3555+
use((env, conf, binder) -> {
3556+
T service = provider.apply(conf);
3557+
binder.bind(type).toInstance(service);
3558+
});
3559+
return this;
3560+
}
3561+
3562+
/**
3563+
* Bind the provided type and object that requires some type of configuration:
3564+
*
3565+
* <pre>{@code
3566+
* {
3567+
* bind(conf -> new MyService(conf.getString("service.url")));
3568+
* }
3569+
* }</pre>
3570+
*
3571+
* @param type Service type.
3572+
* @param provider Service provider.
3573+
* @return This instance.
3574+
*/
3575+
@SuppressWarnings({"unchecked", "rawtypes" })
3576+
public <T> Jooby bind(final Function<Config, T> provider) {
3577+
use((env, conf, binder) -> {
3578+
Object service = provider.apply(conf);
3579+
Class type = service.getClass();
3580+
binder.bind(type).toInstance(service);
3581+
});
3582+
return this;
3583+
}
3584+
34613585
/**
34623586
* Run app in javascript.
34633587
*

0 commit comments

Comments
 (0)