Jesse,
I believe there is a disconnect in the way we approach jit providers.
We both agree that it reduces risk of missing bindings making Guice in
the wild safer and reduces boilerplate. However, where I implicitly
trust API users not to hang themselves, you want to avoid any
possibility for that.
The only use cases JIT providers are built for are supporting type
schemas as opposed to type literals. Informally defined, a type schema
is "a type literal possibly containing a wildcard (?)". So for
instance, taking the Proxy example of before, what we need to express
is
bindJustInTime(new TypeLiteral<Proxy<?>>() {}).toProvider(...);
Given that simplification, the JitProvider interface could be
simplified to
interface JitProvider<T> {
T get(Key<T> key);
}
which makes it quasi-impossible to mis-use it. It would be quite
simple to do a type schema instantiation check, i.e. check that a type
literal is a valid instance of a type schema, in order to implement
this simplification.
Would that address your concerns?
PL
On Jun 1, 9:29 pm, Pascal-Louis <[email protected]> wrote:
> Jesse,
>
> From a team size perspective, I happen to be the VP of Engineering &
> CTO of kaChing.com; We are a large team and our code base is huge. We
> also happen to continuously deploy our code
> (seehttp://eng.kaching.com/2010/05/applied-lean-startup-ideas-continuous....)
> and so proving, automatically, that our software is correct is a must.
>
> What we ended up doing prior to have JIT providers, and which I've
> seen done in other projects, is something along the lines of
>
> ProxyModule(Class... classes) { this.classes = classes; }
> void configure() {
> for (Class c : classes) bind(TypeLiterals.get(Proxy.class,
> c)).to(...);
> }
>
> where TypeLiterals
> ishttp://code.google.com/p/kawala/source/browse/trunk/src/com/kaching/p....
> As such, I don't buy the "grepability" argument of Guice. This is
> simply not a fact.
>
> In our experience, JIT providers reduce the complexity of injection by
> making things much more natural. "Mashaller<Foo>? Sure, I can get
> this!" Versus the "Did I bind it for this specific entry point? What
> about this other entry point?". And yes, without them, you typically
> find these problems at the very last moment when the software is
> already in production.
>
> PL
>
> On Jun 1, 8:32 pm, "[email protected]" <[email protected]> wrote:
>
> > PL,
>
> > On May 31, 8:12 pm, Pascal-Louis <[email protected]> wrote:
>
> > > Over the course of the long weekend, I've implemented this feature and
> > > would love some feedback.
>
> > Thanks for the patch. This has been a long-standing feature request -
> > originally reported in February 2007:
>
> > http://code.google.com/p/google-guice/issues/detail?id=49
>
> > We decided not to offer this functionality because it makes it much
> > more difficult to figure out where a binding comes from. Currently
> > it's possible to use simple tools like grep to find a binding. As soon
> > as we permit autobinders, you really need a runtime to find a biding's
> > source.
>
> > In addition, you can usually accomplish the same thing statically
> > without much problem. To satisfy your Proxy example, you'd write
> > something like this:
>
> > bind(new TypeLiteral<Proxy<Foo>>() {})
> > .toProvider(new ProxyProvider(new TypeLiteral<Proxy<Foo>>()
> > {});
> > bind(new TypeLiteral<Proxy<Bar>>() {})
> > .toProvider(new ProxyProvider(new TypeLiteral<Proxy<Bar>>()
> > {});
>
> > Yes, you will need one bind() statement for each distinct type you
> > ultimately inject. Yes, this is boilerplate. But it's a small amount
> > of obvious boilerplate that saves a lot of indirection.
>
> > One last note...
>
> > Restricting Guice's ability to add indirection is a usability
> > decision, not a technical one. I recently worked on a 20-developer
> > Guice project. In any group of 20 developers, you'll have a few people
> > like you and I: developers who are comfortable with reflection and
> > indirection, and who dislike boilerplate. And you'll have developers
> > who prefer structural simplicity and avoid frameworks where they
> > aren't necessary.
>
> > In the course of the project, a few rockstar developers created a few
> > fancy frameworks that nobody else could maintain. Independently these
> > were all fine, but overall the frameworks made it quite difficult to
> > predict what a body of code would do.
>
> > It's for this reason that Guice tries to avoid magic. Injections
> > require @Inject not because the framework needs them (see
> > PicoContainer) but because they serve as documentation. Just-in-time
> > bindings were a mistake because they can mask a missing binding.
>
> > Guice is a framework intended to scale well as the number of
> > developers on the project grows. It is for this reason that we must
> > sacrifice features that would work great for smaller projects.
>
> > Cheers,
> > Jesse
--
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en.