What determines the lifecycle of a component (object graph) in Dagger 2?

前端 未结 1 959
闹比i
闹比i 2020-11-29 14:41

I\'m trying to wrap my head around scopes in Dagger 2, specifically the lifecycle of scoped graphs. How do you create a component that will be cleaned up when you leave the

相关标签:
1条回答
  • 2020-11-29 15:12

    As for your question

    What determines the lifecycle of a component (object graph) in Dagger 2?

    The short answer is you determine it. Your components can be given a scope, such as

    @Scope
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ApplicationScope {
    }
    
    @Scope
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ActivityScope {
    }
    

    These are useful for you for two things:

    • Validation of scope: a component can only have unscoped providers, or scoped providers of the same scope as your component.

    .

    @Component(modules={ApplicationModule.class})
    @ApplicationScope
    public interface ApplicationComponent {
        Something something();
        AnotherThing anotherThing();
    
        void inject(Whatever whatever);
    }
    
    @Module
    public class ApplicationModule {
        @ApplicationScope //application-scoped provider, only one can exist per component
        @Provides
        public Something something() {
             return new Something();
        }
    
        @Provides //unscoped, each INJECT call creates a new instance
        public AnotherThing anotherThing() {
            return new AnotherThing();
        }
    }
    
    • Allows for sub-scoping your scoped dependencies, thus allowing you to create a "subscoped" component that uses the provided instances from the "superscoped" component.

    This can be done with @Subcomponent annotation, or component dependencies. I personally prefer dependencies.

    @Component(modules={ApplicationModule.class})
    @ApplicationScope
    public interface ApplicationComponent {
        Something something();
        AnotherThing anotherThing();
    
        void inject(Whatever whatever);
    
        ActivityComponent newActivityComponent(ActivityModule activityModule); //subcomponent factory method
    }
    
    @Subcomponent(modules={ActivityModule.class})
    @ActivityScope
    public interface ActivityComponent {
        ThirdThingy thirdThingy();
    
        void inject(SomeActivity someActivity);
    }
    
    @Module
    public class ActivityModule {
        private Activity activity;
    
        public ActivityModule(Activity activity) {
            this.activity = activity;
        }
    
        //...
    }
    
    ApplicationComponent applicationComponent = DaggerApplicationComponent.create();
    ActivityComponent activityComponent = applicationComponent.newActivityComponent(new ActivityModule(SomeActivity.this));
    

    Or you can use component dependencies like so

    @Component(modules={ApplicationModule.class})
    @ApplicationScope
    public class ApplicationComponent {
        Something something(); 
        AnotherThing anotherThing();
    
        void inject(Whatever whatever);
    }
    
    @Component(dependencies={ApplicationComponent.class}, modules={ActivityModule.class})
    @ActivityScope
    public interface ActivityComponent extends ApplicationComponent {
        ThirdThingy thirdThingy();
    
        void inject(SomeActivity someActivity);
    }
    
    @Module
    public class ActivityModule {
        private Activity activity;
    
        public ActivityModule(Activity activity) {
            this.activity = activity;
        }
    
        //...
    }
    
    ApplicationComponent applicationComponent = DaggerApplicationComponent.create();
    ActivityComponent activityComponent = DaggerActivityComponent.builder().activityModule(new ActivityModule(SomeActivity.this)).build();
    

    Important things to know:

    • A scoped provider creates one instance for that given scope for each component. Meaning a component keeps track of its own instances, but other components don't have a shared scope pool or some magic. To have one instance in a given scope, you need one instance of the component. This is why you must provide the ApplicationComponent to access its own scoped dependencies.

    • A component can subscope only one scoped component. Multiple scoped component dependencies are not allowed.

    0 讨论(0)
提交回复
热议问题