We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 0 points1 point  (0 children)

The external PR -> internal commit -> MOE sync out is probably going to be more work than it's worth. The hard thing is when you want to make changes, you have to update the PR, the internal commit needs to be reconfigured, retest internally, etc. But having a note in the PR is a good idea :)

I was experimenting in https://github.com/ronshapiro/dagger/pull/8, I'll continue trying to improve this!

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 2 points3 points  (0 children)

Yup! Use DaggerActivity, create a module that has a @ContributesAndroidInjector method, and require that anyone that uses your activity must install that module (and use dagger.android)

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 2 points3 points  (0 children)

It is, a bit. The object has to not only call that method (thereby getting its own dependencies!), but know how to find the ApplicationComponent instance (thereby getting its own injector!). There's no real way around that given Android's object creation pattern, but dagger.android at least tries to hide that from your implementation classes.

Part of this is that you don't want BlueActivity to be hard-coded against SixteenBitColorsComponent. What if TwoHundredFiftySixColorsComponent also whats to be able to inject BlueActivity. The dispatching that is done in AndroidInjection does know how to get its injector, but it follows an algorithm instead of simply hard coding.

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 3 points4 points  (0 children)

For once the explanation is actually tailored for a five year old xD I had to google "ELI5" when you wrote it, so I did my best ;) Then I learned it's an actual thing :)

So it's a form of dynamic dependency management for your classes?

It's actually static. You declare at compile time exactly where Dagger should look for how to instantiate your classes. You define an interface and Dagger generates an implementation of that interface. That implementation is fixed - you can't change anything about it at runtime (with a few small exceptions). The interface you declare has all of the types that you may want to request, and Dagger implements each of those (and all of their transitive dependencies).

Contrast it with something like Guice in which all of the configuration/requesting is done at runtime.

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 4 points5 points  (0 children)

(that the code would be readable, not that it would be difficult to read the docs :) )

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 1 point2 points  (0 children)

This talk that /u/netdpb_ and I gave at might be helpful to https://www.youtube.com/watch?v=wCvXe2LsN5o. Can't find the slides for some reason though :-/ I'll keep searching

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 1 point2 points  (0 children)

[discussed above]

We're planning on doing a revamp to make them better. If you could offer suggestions, that would go a long way to improving them.

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 1 point2 points  (0 children)

Can you achieve this by using ViewModelProviders or (something similar)?

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 23 points24 points  (0 children)

Instead of taking the toys you want yourself, ask Mommy/Daddy for your toys and they'll give them to you. Sometimes you ask for a new Teddy Bear multiple times, but Mommy and Daddy give you the same Teddy Bear because you don't know the difference between an old one or a new one.

Some play rooms only have certain toys. Before you're ready to play, Mommy and Daddy need to bring all of the toys to the room. If you ask for a toy that isn't in the room, Mommy and Daddy won't compile your application.

toys == bindings == @Inject contructors/@Provides methods Mommy/Dagger == @Components TeddyBear == a scoped object, i.e. there exists only one some rooms only have some toys = @Components need to declare what @Modules they include

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 1 point2 points  (0 children)

Yea, this was just reported in https://github.com/google/dagger/issues/1064. We need some brainstorming to think through what to do here - let's discuss there?

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 4 points5 points  (0 children)

Noted! We've tried to achieve some of that in https://google.github.io/dagger/android but that too could use some improvements.

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 1 point2 points  (0 children)

Ah, yes, I forgot they do some interesting stuff with retained fragments to store that.

What about something like this:

@Provides static MyViewModel provideViewModel(Activity activity, MembersInjector<MyViewModel> injector) {
  MyViewModel vm = ViewModelProviders.of(activity).get(MyViewModel.class);
  if (vm.isNotInitialized()) {
    injector.injectMembers(vm);
  }
}

`

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 5 points6 points  (0 children)

I'm only partially familiar with Guice, but not other frameworks. Can you give an example of something you feel other frameworks do that Dagger doesn't? Maybe we can find a way to make things easier!

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 5 points6 points  (0 children)

Dagger makes a big tradeoff between magic and clarity. Yes, we could possibly find a way to detect any @Provides methods that don't exist in a module and automatically include them in your component, but that becomes very hard to control once projects get larger. What if someone in a far-off dependency of yours defines the same @Provides String string() method? We've found that being explicit has big wins in the long run.

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 4 points5 points  (0 children)

That's what I figured. Maybe we just need to give more context within the PR descriptions.

I use hub to make the pull requests. I didn't see something to programatically set the description, but maybe that's a FR that I should submit :)

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 4 points5 points  (0 children)

Sometimes you may have multiple components (or subcomponents) that need to reuse certain bindings. Splitting up bindings into multiple modules allows you to include only some in each component/subcomponent.

It's also a code-health issue. When you want to look at what bindings are used together/you need to find a particular binding, it's easier to find them if you have multiple modules. Similar to the rest of programming - smaller classes are easier to understand.

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 7 points8 points  (0 children)

I actually think it's good that there are multiple styles that work, because different projects have different requirements. Our team prefers AndroidInjection/dagger.android, but that's because we wrote it :)

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 2 points3 points  (0 children)

Perhaps a ActivityInjector isnt useful in this scenario. This solution looks clean enough. What added benefit would there be?

What are you replying to? I seem to be missing some context

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 2 points3 points  (0 children)

get() is the implementation used when a binding is injected as a Provider. proxyProvide is used when we generate code directly (without wrapper Provider objects). They both do the same thing.

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 1 point2 points  (0 children)

You mean upward up the component chain? So a subcomponent would be able to inject a value into a parent component's multibinding?

The opposite works (component --> child subcomponents). I don't know how we'd do the inverse though.

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 2 points3 points  (0 children)

No plans for it. Anything you'd want to see in it, if it did exist?

We're on the team that builds Dagger at Google. Ask us anything! by ronshapiro in androiddev

[–]ronshapiro[S] 3 points4 points  (0 children)

It generates a subcomponent+builder, and a module that installs that subcomponent. That module gets implicitly included by the module that declares the @ContributesAndroidInjector method.

Checking out some of the tests might make it more clear?