Why do Dagger components have to declare their sco

2019-06-26 08:04发布

Why do I have to annotate a Dagger component with the scopes it's going to use? Why is it not enough to annotate the class itself?

2条回答
叼着烟拽天下
2楼-- · 2019-06-26 08:42

Because scopes by themselves don't mean anything. It's the components and their relationships that introduce meaning to scopes.

Unscoped objects can be provided from any component if their dependencies are available. Since they are unscoped there will be a new object created every time that you call their provider. A scoped object will share the lifecycle of the component of the same scope and it will only ever be created once per component. If you recreate the component, you recreate all the objects within its scope. This is where things would get tricky.

Say you have the following setup: a component, and a subcomponent, as it is often the case.

@Component interface MyComponent {}

@Subcomponent interface MySubComponent {}

Now let's say we have two classes, Foo in @FooScope and Bar in @BarScope. Both support constructor injection and both have the scope annotation on their respective class. Let's say we add a provision method for the two to our subcomponent:

@Subcomponent
interface MySubComponent {

  Foo getFoo();

  Bar getBar();
}

Now the big question: Where do Foo or Bar get created and which component's "lifecycle" do they share?

We do know that Foo and Bar are in different scopes but that's about it. If one depends on the other we may be able to deduce that one resides in the (parent) component and the other in the subcomponent since one can only ever depend on objects of the same or a higher scope, but this will only ever work for this simple setup and will leave us with uncertainty again if we ever decide to add a third component to this setup.

What happens if we have 3 scopes, but only two components? Which of the two components should host two scopes (if that even makes sense)? Or if it were to report an error, which scope is "the wrong one"? There would simply be no way of knowing for sure.

Those problems will disappear if you also add a scope to the component. It will now be clear which component handles which (scoped) objects, and it is easy enough to report errors when there are unknown scopes introduced.

查看更多
我命由我不由天
3楼-- · 2019-06-26 09:00

We need localization because we do not want all our dependencies to live as long as the application, and there are cases when we want our dependencies to not share the same state by being the same object. Activities have their own Presenters or ViewModels, 1 or more Presenters or ViewModels may require a single Interactor and Interactors depends on the data layer. Dagger 2 provides @Scope as a mechanism to handle scoping. Scoping allows you to preserve the object instance and provide it as a local singleton for the duration of the scoped component. Scopes cares about keeping single instance of class as long as its scope exists. In practice it means that instances scoped in @ApplicationScope lives as long as Application object. @ActivityScope keeps references as long as Activity exists (for example we can share single instance of any class between all fragments hosted in this Activity). In short - scopes give us “local singletons” which live as long as scope itself.

查看更多
登录 后发表回答