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 <sber...@gmail.com> 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 <
> nate.bauernfe...@gmail.com> 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 <fourofcl...@gmail.com>
>> 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 google-guice+unsubscr...@googlegroups.com.
>>> To post to this group, send email to google-guice@googlegroups.com.
>>> 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 google-guice+unsubscr...@googlegroups.com.
>> To post to this group, send email to google-guice@googlegroups.com.
>> 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 google-guice+unsubscr...@googlegroups.com.
> To post to this group, send email to google-guice@googlegroups.com.
> 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 google-guice+unsubscr...@googlegroups.com.
To post to this group, send email to google-guice@googlegroups.com.
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to