Open GoogleCodeExporter opened 9 years ago
We discussed this today, and our best idea is to have an @New annotation (not a
binding annotation) for provider
methods, plus a toConstant() bind target.
Original comment by limpbizkit
on 8 Aug 2008 at 1:44
I mistyped: I meant a toConstructor() bind target.
Original comment by limpbizkit
on 8 Aug 2008 at 1:46
Just for clarification: Are you discussing
1. a kind of post construction hook (which was also discussed in other issues
and
could be realized using scopes),
2. a solution for the so called robot-leg problem, that only needs one injector
(parent injector concept comes along with the "one injector per leg"-problem)
3. or something completely different?
Original comment by sven.lin...@gmail.com
on 8 Aug 2008 at 3:06
Plan:
We'll Introduce a special binding annotation called '@New'. It is an error to
bind to @New by hand; ie. it's an
error to do this:
bind(Foo.class).annotatedWith(New.class).to(...)
When an injection point asks for an @New Foo, we create a default binding for
the constructor of Foo. Foo
must always be a concrete class with a Guice-invokable constructor (ie. @Inject
or public no-args).
Complications:
What happens if Foo.class is annotated @Singleton? Do I get the same instance
each time I inject @New Foo?
Or different ones?
Suppose I inject both Foo and @New Foo. If Foo.class is annotaed @Singleton, do
I get the same instance?
SPI Considerations:
I'm tempted to make it so @New is 1:1 with constructor bindings. For example,
given this code:
bind(Bar.class).to(BarImpl.class);
Guice would create 3 bindings:
Bar.class linked to BarImpl.class (explicit)
BarImpl.class linked to @New BarImpl.class (default)
@New BarImpl to its own constructor (built-in)
Syntactic Sugar:
We confound linked bindings and constructor bindings in the current Guice. It
means you can't solve the
turkey bacon problem [http://tinyurl.com/turkeybaconproblem]. So I'd like to
introduce some syntactic sugar
related to @New:
bind(Bar.class).toConstructor(BarImpl.class);
is syntactic sugar for:
bind(Bar.class).to(Key.get(BarImpl.class, New.class));
Original comment by limpbizkit
on 28 Nov 2008 at 7:30
Deferred to the next release so we can work out the scoping issues.
Original comment by limpbizkit
on 25 Dec 2008 at 4:30
We've implemented toConstructor() bindings:
bind(Foo.class).toConstructor(Foo.class.getConstructor(Bar.class, Baz.class));
It's possible to easily implement @New as a simple built-in JIT binding on top
of the toConstructor support.
Original comment by limpbizkit
on 21 Jun 2009 at 6:21
Issue 485 has been merged into this issue.
Original comment by sberlin
on 23 May 2010 at 12:26
toConstructor itself solves the TurkeyBacon problem as described @
http://tinyurl.com/turkeybaconproblem . It would be solved by doing:
public class BritishModule extends AbstractModule {
public void configure() {
bind(Bacon.class).to(UncookedBacon.class);
bind(Bacon.class).annotatedWith(Names.named("Turkey").to(TurkeyBacon.class);
bind(Bacon.class).annotatedWith(Names.named("Cooked")).toConstructor((Constructo
r)InjectionPoint.forConstructorOf(Bacon.class).getMember());
}
}
.. a little bit unwieldy code-wise, but it works.
Is @New still needed? It can be worked around pretty easily by:
bind(Bar.class).annotatedWith(named("new")).toConstructor((Constructor)Injection
Point.forConstructorOf(BarImpl.class).getMember());
and later using it was @Inject Baz(@Named("new") Bar bar) { ... }
In other words, instead of toConstructor being syntactic sugar for @New, @New
would
be syntactic sugar for toConstructor.
It'd be pretty easy to hack up, either way.
Original comment by sberlin
on 23 May 2010 at 2:21
FYI - I committed a test in r1166 that asserts that toConstructor solves the
turkeybacon problem.
Original comment by sberlin
on 23 May 2010 at 2:32
Thinking about this some more... it looks like attempts to introduce @New would
introduce a lot confusion. For example, if Bar is linked to BarImpl.class, what
would "@New Bar" return? What if Bar was linked to Provider<Bar>, or @Provides
Bar.
Would @New just be disallowed on interfaces because of that confusion?
I think we're safest adding an easy-to-use "find the right constuctor" method,
something like <T> Constructor<T> Constructors.forConstructorOf(Class<T>
clazz), to
reduce the boilerplate from comment #8 of using InjectionPoint to find the right
constructor. Then users can use it to create their own "new" bindings,
annotated
with whatever they'd like. That way, things like "@New Bar" would be defined,
because the user would have had to define it.
I'm for closing this as "will not fix" -- please chime in if you think
otherwise!
Original comment by sberlin
on 23 May 2010 at 3:18
Closing as fixed because toConstructor allows this with some configuration
(bind your object with toConstructor and a custom @New annotation).
Original comment by sberlin
on 25 Oct 2010 at 12:15
Original issue reported on code.google.com by
crazybob...@gmail.com
on 7 Aug 2008 at 12:57