I guess the module would only work if:
      a) The user didn't specify an implementation type for Foo
  or b) The implementation type had the exact same generic args as Foo.

So the workable scenarios would be:

a)
  class Foo<T> {
    interface Factory {
      Foo<T>  create(T t);
    }
  }
  Module {
    configure() {
       install(new FactoryModuleBuilder().build(Foo.Factory.class));
    }
 }

b)
  // same Foo + FooFactory from A
  class FooImpl<T> extends Foo<T> { ... }
  Module {
    configure() {
      install(new FactoryModuleBuilder().implement(Foo.class,
FooImpl.class).build(Foo.Factory.class);
    }
 }


While (b) is technically workable, validating the generics are the same is
a pretty hard problem.
(a) is much easier to do, but would require adding validation to fail
properly in the scenarios we can't handle (right now the validation catches
(a) too... loosening it to allow (a) but disallow (b) and everything else
becomes a harder problem).

sam

On Wed, May 27, 2015 at 10:54 AM Nate Bauernfeind <
[email protected]> wrote:

> I must still be missing the point, Sam. What would you expect the Guice
> module to look like?
>
> Is this your understanding of what the feature is:
> interface Foo<T> {
>   ...
> }
>
> interface FooGuiceFactory {
>   Foo<Object> create(Object o)
> }
>
> Currently, you could then write an instance of the interface you really
> want:
> class FooFactory {
>   @Inject private final FooGuiceFactory fooFactory;
>
>   <T> Foo<T> create(T t) {
>     return (Foo<T>)fooFactory.create(t);
>   }
> }
>
> That seems underwhelming compared to what I was imagining. It also seems
> like it would be pretty trivial to implement -- If you think people would
> use it I would be interested in giving it a shot.
>
> On Wed, May 27, 2015 at 7:58 AM Sam Berlin <[email protected]> wrote:
>
>> If <T> is only used as an assisted param (and *not* used by any injected
>> ones), then I think we can get away with just ignoring it. The compiler
>> will make sure the types are safe, and we can just pretend T is its erased
>> type.  So long as the user supplies us the T and we don't have to worry
>> about locating anything that references a T... there won't be any unknowns.
>>
>> sam
>>
>> On Wed, May 27, 2015, 1:08 AM Nate Bauernfeind <
>> [email protected]> wrote:
>>
>>> Sam, I don't see how it could ever work if T itself had generic
>>> parameters. I can only see two solutions 1) push the burden onto the client
>>> of the factory and force them to provide a type literal or 2) the generic
>>> factory methods only work for a subset of types. In my opinion option 2 is
>>> useless: you should be able to bind Foo[List[String]] to a different
>>> implementation than a Foo[List[Int]] for example.
>>>
>>> The current solution is to add the type parameter to the factory, which
>>> requires a one-to-one binding per factory. I thought that people don't like
>>> this option because they'd like to remove the one-to-one binding
>>> restriction, or perhaps they don't want to inject `n` different Factories
>>> someplace. (There might be other advantages I'm being shortsighted about;
>>> these are just the two that pop out as large costs.)
>>>
>>> Removing these particular restrictions is clearly a one-to-many binding
>>> argument. In fact, a non one-to-many implementation is relatively
>>> straightforward! Here's an example in scala (for terseness):
>>>
>>> object T extends App {
>>>   class Foo[T] (@Assisted t: T) { override def toString = s"Foo($t)" }
>>>   class FooString @Inject()(@Assisted t: String) extends Foo[String](t)
>>>   class FooInt @Inject()(@Assisted t: Integer) extends Foo[Integer](t)
>>>
>>>   trait F {
>>>     def create(t: String): Foo[String]
>>>     def create(i: Int): Foo[Integer]
>>>   }
>>>
>>>   val mod = new ScalaModule {
>>>     def configure(): Unit = {
>>>       install(new FactoryModuleBuilder()
>>>         .implement(typeLiteral[Foo[String]], typeLiteral[FooString])
>>>         .implement(typeLiteral[Foo[Integer]], typeLiteral[FooInt])
>>>         .build(typeLiteral[F]))
>>>     }
>>>   }
>>>
>>>   import net.codingwell.scalaguice.InjectorExtensions._
>>>   val injector = Guice.createInjector(mod)
>>>   println(injector.instance[F].create(42))
>>>   println(injector.instance[F].create("hello world"))
>>> }
>>>
>>> There are a couple of issues that you can't really get around. 1) You
>>> need to subclass Foo or else the constructor loses the parameter's type
>>> information due to erasure. 2) you need to enumerate each create method in
>>> the factory. 3) you need one implement call per T in your factory. And
>>> subtly, 4) the method `def create[T](t: T): Foo[T]` doesn't exist!
>>>
>>> This is three times as much work as would be nice, but due to JVM
>>> restrictions I don't think you can remove the additional work without
>>> requiring TypeReferences on the create method.
>>>
>>> Does this shed light from my perspective, or am I misunderstanding the
>>> problem?
>>>
>>> On Tue, May 26, 2015 at 6:16 PM Sam Berlin <[email protected]> wrote:
>>>
>>>> The "many to one binding" thing isn't really the reason since it's not
>>>> a binding, it's just a method call in your factory.
>>>>
>>>> For assistedinject, the lack of being able to specify <T> on the method
>>>> w/o also specifying it on the factory is really just a no one's had the
>>>> time to sit down and figure out how to do it.  See the bug @
>>>> https://github.com/google/guice/issues/218 .
>>>>
>>>> Implementation's @
>>>> https://github.com/google/guice/blob/master/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
>>>> if you want to give it a go.
>>>>
>>>> sam
>>>>
>>>> On Tue, May 26, 2015 at 6:08 PM Nate Bauernfeind <
>>>> [email protected]> wrote:
>>>>
>>>>> Assuming you meant:
>>>>> interface FooFactory {
>>>>>   <T> Foo<T> create(T bar);
>>>>> }
>>>>>
>>>>> No, this does not work. It would require one-to-many bindings, which,
>>>>> if you read the recent forum's history, is not supported.
>>>>>
>>>>> This is the closest you can get. I use it pretty frequently:
>>>>> interface FooFactory<T> {
>>>>>   Foo<T> create(T bar);
>>>>> }
>>>>>
>>>>> You will need to use type literals to capture the generic types when
>>>>> you create the assisted inject factories. (See:
>>>>> http://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/TypeLiteral.html
>>>>> )
>>>>>
>>>>> Nate
>>>>>
>>>>> On Tue, May 26, 2015 at 5:52 PM Brad Micholson <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> Is there currently any way to use type inference in an assisted
>>>>>> inject factory?
>>>>>> For example, is there any way to use an interface like the following
>>>>>> as an assisted inject factory?
>>>>>>
>>>>>>
>>>>>> interface FooFactory
>>>>>> {
>>>>>>   Foo<T> create(T bar);
>>>>>> }
>>>>>>
>>>>>> --
>>>>>> 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 [email protected].
>>>>>> To post to this group, send email to [email protected].
>>>>>> Visit this group at http://groups.google.com/group/google-guice.
>>>>>> To view this discussion on the web visit
>>>>>> https://groups.google.com/d/msgid/google-guice/3b354f12-1927-44fb-ac0d-94b28941ced6%40googlegroups.com
>>>>>> <https://groups.google.com/d/msgid/google-guice/3b354f12-1927-44fb-ac0d-94b28941ced6%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>  --
>>>>> 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 [email protected].
>>>>> To post to this group, send email to [email protected].
>>>>> Visit this group at http://groups.google.com/group/google-guice.
>>>>>
>>>> To view this discussion on the web visit
>>>>> https://groups.google.com/d/msgid/google-guice/CAHNex995t_ae%2BKnFpHSxB5vVHLNkP%2BhY%2BdCt5-8VQOpM1BsHqw%40mail.gmail.com
>>>>> <https://groups.google.com/d/msgid/google-guice/CAHNex995t_ae%2BKnFpHSxB5vVHLNkP%2BhY%2BdCt5-8VQOpM1BsHqw%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>
>>>>
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>  --
>>>> 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 [email protected].
>>>> To post to this group, send email to [email protected].
>>>> Visit this group at http://groups.google.com/group/google-guice.
>>>>
>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/google-guice/CAJEBNUdoCzATtdVH2zBS%2BZgdjQYUCWbq9gn2xh-AvfzEwkB6Dg%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/google-guice/CAJEBNUdoCzATtdVH2zBS%2BZgdjQYUCWbq9gn2xh-AvfzEwkB6Dg%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>
>>>
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>  --
>>> 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 [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at http://groups.google.com/group/google-guice.
>>>
>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/google-guice/CAHNex98Xi8O3f6z%3Dw3PXtF%2BCsJYyrfoK2oeWrOKgVkyDMzrr9g%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/google-guice/CAHNex98Xi8O3f6z%3Dw3PXtF%2BCsJYyrfoK2oeWrOKgVkyDMzrr9g%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>
>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>  --
>> 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 [email protected].
>> To post to this group, send email to [email protected].
>> Visit this group at http://groups.google.com/group/google-guice.
>>
> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/google-guice/CAJEBNUc4NPP3AGpu7%3DH-5vB3m59XikRnAA4-cmaET7S_vEhi%3DQ%40mail.gmail.com
>> <https://groups.google.com/d/msgid/google-guice/CAJEBNUc4NPP3AGpu7%3DH-5vB3m59XikRnAA4-cmaET7S_vEhi%3DQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>
>
>> For more options, visit https://groups.google.com/d/optout.
>>
>  --
> 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 [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/google-guice.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/google-guice/CAHNex9-1TRd4uVkXM6gtpVsAc%2BSx%2Bwb6s%3Dd5rJ6bmq9SGsXeMA%40mail.gmail.com
> <https://groups.google.com/d/msgid/google-guice/CAHNex9-1TRd4uVkXM6gtpVsAc%2BSx%2Bwb6s%3Dd5rJ6bmq9SGsXeMA%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-guice/CAJEBNUcv2KmP%3D3yd6v2aNxpNC1uWQ2Rx5prfxmXVJ1J3RHMqMw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to