Skip to content
This repository has been archived by the owner on Aug 26, 2021. It is now read-only.

Proposal: Dagger 2.0 #366

Closed
gk5885 opened this issue Dec 10, 2013 · 14 comments
Closed

Proposal: Dagger 2.0 #366

gk5885 opened this issue Dec 10, 2013 · 14 comments

Comments

@gk5885
Copy link
Contributor

gk5885 commented Dec 10, 2013

For a while now, we have floated ideas about full-graph generation and how we might evolve Dagger from half static, half runtime to a fully static, fully generated, fully awesome DI solution. In working with Dagger in a large application on the server side we ran into some particular pain points that shaped how we might want a static solution to look. So, I present a proposal for Dagger 2.0 that hopefully bridges the gaps between what's suitable on Android and what makes sense for very large applications, with ridiculous numbers of bindings.

https://docs.google.com/document/d/1fwg-NsMKYtYxeEWe82rISIHjNrtdqonfiHgp8-PQ7m8/edit?usp=sharing

Everybody should be able to comment. Feedback on this bug and in the doc are both welcome.

I have also developed a prototype for this solution. It works pretty well, but the code is still slightly embarrassing. I will try to get that cleaned up and into a github repository shortly. I'll update the bug when that happens.

@cgruber
Copy link
Collaborator

cgruber commented Dec 10, 2013

I'm excited.

@JakeWharton
Copy link
Member

It's a lot to take in but exciting indeed! I'll have to pass through the
doc more carefully soon.


Jake Wharton
http://about.me/jakewharton

On Tue, Dec 10, 2013 at 1:54 PM, Christian Edward Gruber <
notifications@github.com> wrote:

I'm excited.


Reply to this email directly or view it on GitHubhttps://github.com//issues/366#issuecomment-30271953
.

@codefromthecrypt
Copy link
Contributor

Interesting design WIP. Thanks for putting it together!

@gk5885
Copy link
Contributor Author

gk5885 commented Dec 13, 2013

OK, here's the (still somewhat messy) code: https://github.com/gk5885/dagger/tree/pipe-dream

I recommend taking a look at how this all comes together in the sample. I'm working thorough the features that enable the more interesting bits of graph composition. I'll update this issue and the sample code when I get that stuff running.

@cgruber
Copy link
Collaborator

cgruber commented Feb 14, 2014

Just as a process FYI, the first few commits have gone in internally (by @gk5885) in Google's internal repo, just starting to lay out the APIs. Very quickly I'm going to branch off the 1.x stuff (per our discussions with Jesse and Bob), so we can start moving forward on 2.x as the main trunk of development, making the 1.x branch effectively a maintenance branch (though still aggressively maintained until we decide otherwise as a project.) So expect to see stuff before the end of the quarter.

@codefromthecrypt
Copy link
Contributor

sounds great.

@johnlcox
Copy link

With the ObjectGraph being deprecated will there be something equivalent to ObjectGraph#get(type)?

@JakeWharton
Copy link
Member

You'll have to use a @Component interface for creating types.

@Component(module = FooModule.class)
interface FooComponent {
  Foo getFoo();
}

Dagger will generate an implementation of this interface to which you can pass a module.

FooComponent fooComponent = new DaggerComponent_FooComponent(new FooModule());
Foo foo = fooComponent.getFoo();

While it seems like a lot to write for just one type, in practice you won't use it for a single type so the overhead of the code in relation to what you use it for won't be as drastic.

@johnlcox
Copy link

So what if you just have a Class<?> that you need to get an instance of?

For instance for dagger/jersey integration: https://github.com/johnlcox/dagger-servlet/blob/master/dagger-jersey/src/main/java/com/leacox/dagger/jersey/DaggerComponentProviderFactory.java#L180

@cgruber
Copy link
Collaborator

cgruber commented Apr 24, 2014

You'll make an interface, like:

@Component(...)
interface MyApplicationGraph {
  public Thing1 getParticularThing();
  public void injectFoo(Foo foo);
  //...
}

And that is your graph. Dagger 2.0 generates the implementation, which you just use. We are considering a sort of compatibility thingy, where we turn ObjectGraph into an interface with the get(Class<?> clazz) method. In the generated implementations, the get() method (and inject() method) would simply have a conditional that routes those methods to the appropriate strongly typed getter/injector method on your interface, or throw an exception.

Generally, the new pattern would not be to bother with that, but it would allow for some existing infrastructure to be re-used while more robust infrastructure is built up.

Ultimately, the @Component interface YourGraph { ... } is more powerful, in that it permits you to offer complex types (with concrete type variables, like List<String>) which we couldn't offer through the generalized get() method. So this above-mentioned mapping would largely be intended for backward compatibility with existing infrastructure.

@gk5885 gk5885 closed this as completed Apr 24, 2014
@gk5885 gk5885 reopened this Apr 24, 2014
@cgruber
Copy link
Collaborator

cgruber commented Apr 24, 2014

Actually, arbitrary last-minute instantiation via dagger was never viable - if you don't express the class Foo via @Module(injects=Foo.class) then you can't ask graph.get(Foo.class) for an instance anyway. In this case, you just make a method public Foo getFoo(). But for arbitrary classes, that was never how Dagger was designed.

@cgruber
Copy link
Collaborator

cgruber commented Apr 24, 2014

Hmm. Looking at the Jersey example, it seems like it is actually building a lot of reflective API on top of Dagger... but I think the ObjectGraph-compatibility approach might suit there. That said, this is particularly intense reflective analysis on what is supposed to be a compile-time framework... I'm thinking some of it could be potentially replaced with generics - instead of all the reflective lookup just have DaggerInjectedComponentProvider and have your component be T, instead of ObjectGraph. But that's off the top of my head. I'm going to build (or collaborate on) some similar infrastructure around servlet engines and for android internally in the next six to eight weeks, and I think we'll learn a lot about how to best harness Dagger 2.0 in other infrastructure.

@johnlcox
Copy link

That definitely makes sense. The dagger-jersey project was a quick attempt at getting dagger integration with Jersey and it works, but does require marking a lot of classes as injects on the module.

@JakeWharton
Copy link
Member

This happened.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants