Discussion:
Assisted Inject Implement using Provider as Target
Matthew Madson
2016-12-02 21:42:18 UTC
Permalink
Hi Guice Devs:

I assume this is a feature request but I was wondering if there was a way
to do something like the following:

interface Factory {

@Named("secure")
CloseableHttpClient createSecureClient();

@Named("insecure")
CloseableHttpClient createSecureClient();
}

class Module extends AbstractModule {
@Override
protected void configure() {
install(new FactoryModuleBuilder()
.implement(CloseableHttpClient.class, Names.named("secure"),
getProvider(Key.get(CloseableHttpClient.class, Names.named("secure"))))
.implement(CloseableHttpClient.class, Names.named("insecure"),
getProvider(Key.get(CloseableHttpClient.class, Names.named("insecure"))))
.build(Factory.class));
}

@Provides
@Named("secure")
CloseableHttpClient provideSecureHttpClient() {
return HttpClientBuilder.create()....build();
}

@Provides
@Named("insecure")
CloseableHttpClient provideInsecureHttpClient() {
return HttpClientBuilder.create().setSslcontext(SSLContexts.custom().
loadTrustMaterial(...).build()).build();
}
}

Basically I'd like to have the factory method bound to a provides method.

Best,
Matt
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice+***@googlegroups.com.
To post to this group, send email to google-***@googlegroups.com.
Visit this group at https://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/18619274-7912-438c-9ae7-e446632fb882%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Tavian Barnes
2016-12-03 19:24:34 UTC
Permalink
Since there are no assisted parameters here, nothing prevents you from just
writing an implementation of Factory by hand.

But if there were assisted parameters, how would you expect it to work?
Post by Matthew Madson
I assume this is a feature request but I was wondering if there was a way
interface Factory {
@Named("secure")
CloseableHttpClient createSecureClient();
@Named("insecure")
CloseableHttpClient createSecureClient();
}
class Module extends AbstractModule {
@Override
protected void configure() {
install(new FactoryModuleBuilder()
.implement(CloseableHttpClient.class, Names.named("secure"),
getProvider(Key.get(CloseableHttpClient.class, Names.named("secure"))))
.implement(CloseableHttpClient.class, Names.named("insecure"),
getProvider(Key.get(CloseableHttpClient.class, Names.named("insecure"))))
.build(Factory.class));
}
@Provides
@Named("secure")
CloseableHttpClient provideSecureHttpClient() {
return HttpClientBuilder.create()....build();
}
@Provides
@Named("insecure")
CloseableHttpClient provideInsecureHttpClient() {
return HttpClientBuilder.create().setSslcontext(SSLContexts.custom().
loadTrustMaterial(...).build()).build();
}
}
Basically I'd like to have the factory method bound to a provides method.
Best,
Matt
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice+***@googlegroups.com.
To post to this group, send email to google-***@googlegroups.com.
Visit this group at https://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/f552f940-0f6a-4387-b47d-f381e0349e0d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Matthew Madson
2016-12-04 08:16:51 UTC
Permalink
Thanks for the suggestion re traditional factory; that's actually exactly what I ended up doing but the amount of boilerplate was a bit disappointing. I'll admit I didn't really give the matter much thought beyond my use case so assisted Inject parameters do pose a bit of a problem from a more general design perspective. My suggesting, we're the feature to be implemented, would be to permit assisted annotated parameters on either the provides method or the constructor of the provider type should one exist. I can see how this introduces a bit of perhaps unnecessary complexity since the results of assisted provides methods can longer be injected without use of the assisted factory, but then again I think it could all work out with a bit of documentation.
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice+***@googlegroups.com.
To post to this group, send email to google-***@googlegroups.com.
Visit this group at https://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/1e67532a-4949-4d8e-801f-5527eecaaaf6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Tavian Barnes
2016-12-04 21:47:08 UTC
Permalink
Post by Matthew Madson
Thanks for the suggestion re traditional factory; that's actually exactly
what I ended up doing but the amount of boilerplate was a bit
disappointing. I'll admit I didn't really give the matter much thought
beyond my use case so assisted Inject parameters do pose a bit of a problem
from a more general design perspective. My suggesting, we're the feature to
be implemented, would be to permit assisted annotated parameters on either
the provides method
@Provides definitely can't handle this. It may be possible to implement
some other annotation like @AssistedProvides though, but I haven't thought
about it in detail.
Post by Matthew Madson
or the constructor of the provider type should one exist.
This is already how assisted inject works. It didn't work for you in this
case, because you don't have a simple subclass, but rather a whole
expression to run that produces the implementation. But if you just had
InsecureHttpClient and SecureHttpClient implementation classes, with
@AssistedInject constructors, everything would work automagically.
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice+***@googlegroups.com.
To post to this group, send email to google-***@googlegroups.com.
Visit this group at https://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/66ca4331-ce15-424e-b134-d3312f4f3cf2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Matthew Madson
2016-12-05 22:57:20 UTC
Permalink
Hi Tavian,

I'm curious why you think that @Provides method can't handle it. Wouldn't
the following be sufficient?

install(new FactoryModuleBuilder()
// this line would tell guice that instances of Foo must come from
FooFactory and the provider is only
// to be used by the assisted inject FooFactory proxy
.implement(Foo.class, (Provider<Foo>) getProvider(Foo.class))
.build(FooFactory.class)

@Provides
Foo provideFoo(@Assisted String someRuntimeString) {
return new Foo(someRuntimeString);
}

OR

public class FooProvider implements Provider<Foo> {

private final String someRuntimeString;

@Inject
public FooProvider(final String someRuntimeString) {
this.someRuntimeString = someRuntimeString;
}

@Override
public Foo get() {
return new Foo(this.someRuntimeString);
}
}


//if other code tried to inject either Foo or Provider<Foo> there should be
a runtime error stating something like, instances of Foo must be obtained
from the assisted inject factory FooFactory.class


I'll admit that in the absence of assisted params, @Provides becomes much
more confusing if it's not also eligible to be injected in other contexts.
I suppose you could allow it under such circumstances and only yell if
assisted params are defined.

Anyway, clearly this feature request needs to be fleshed out a bit more. I
don't really have the cycles to implement. Do you happen to know if a
tracker exists where I could suggest this as a feature and keep an eye on
it should it ever make its way into production?
Post by Tavian Barnes
Post by Matthew Madson
Thanks for the suggestion re traditional factory; that's actually exactly
what I ended up doing but the amount of boilerplate was a bit
disappointing. I'll admit I didn't really give the matter much thought
beyond my use case so assisted Inject parameters do pose a bit of a problem
from a more general design perspective. My suggesting, we're the feature to
be implemented, would be to permit assisted annotated parameters on either
the provides method
@Provides definitely can't handle this. It may be possible to implement
about it in detail.
Post by Matthew Madson
or the constructor of the provider type should one exist.
This is already how assisted inject works. It didn't work for you in this
case, because you don't have a simple subclass, but rather a whole
expression to run that produces the implementation. But if you just had
InsecureHttpClient and SecureHttpClient implementation classes, with
@AssistedInject constructors, everything would work automagically.
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice+***@googlegroups.com.
To post to this group, send email to google-***@googlegroups.com.
Visit this group at https://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/c595c012-fedb-433c-a7f9-bfb9c3da63ac%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...