Dagger2 : How to use @Provides and @Binds in same module

前端 未结 4 2260
无人及你
无人及你 2020-12-18 18:20

I\'m using the new Dagger2 (ver 2.11) and I\'m using the new features like AndroidInjector, and ContributesAndroidInjector. I have an activity subc

相关标签:
4条回答
  • 2020-12-18 18:25

    This is other type solution: Add modules to other module after that you can call top module in your component interface. It can be more efficiency because you can use abstract and static.

    Details and examples are below:

    For example, we have an component interface and two modules such as ComponentClasses, Module_ClassA and Module_ClassB.

    Module_ClassA is:

    @Module
    public class Module_ClassA {
    
       @Provides
       static ClassA provideClassA(){
    
         return new ClassA();
       }
    }
    

    Module_ClassB is:

    @Module
    abstract class Module_ClassB {
    
       @Binds
       abstract ClassB bindClassB(Fragment fragment); //Example parameter
    }
    

    So now, we have two models. If you want use them together, you can add one of them to other. For example: You can add Module_ClassB to Module_ClassA:

    @Module(includes = Module_ClassB.class)
    public class Module_ClassA {
    
       @Provides
       static ClassA provideClassA(){
    
         return new ClassA();
       }
    }
    

    Finally, you do not need to add both modules to your component class. You can only add your top module on your component class, like that:

    ComponentClasses is:

    @Component(modules = Module_ClassA)
    public interface ComponentClasses {
    
       //Example code 
       ArrayList<CustomModel> getList();
    
    }
    

    However, you should be careful because you need to add your top module. Thus, Module_ClassA added on ComponentClasses interface.

    @canerkaseler

    0 讨论(0)
  • 2020-12-18 18:27

    @Binds and @ContributesAndroidInjector methods must be abstract, because they don't have method bodies. That means that they must go on an interface or abstract class. @Provides methods may be static, which means they can go on abstract classes and Java-8-compiled interfaces, but non-static ("instance") @Provides methods don't work on abstract classes. This is explicitly listed in the Dagger FAQ, under the sections "Why can’t @Binds and instance @Provides methods go in the same module?" and "What do I do instead?".

    If your @Provides method doesn't use instance state, you can mark it static, and it can go onto an abstract class adjacent to your @Binds methods. If not, consider putting the bindings like @Binds and @ContributesAndroidInjector into a separate class--possibly a static nested class--and including that using the includes attribute on Dagger's @Module annotation.

    0 讨论(0)
  • 2020-12-18 18:27

    If you are in kotlin world, another alternative is to leverage companion object

    @Module
    abstract class MyDaggerModule {
    
        @Binds
        abstract fun provideSomething(somethingImpl: SomethingImpl): Something
    
        companion object {
    
            @Provides
            fun provideAnotherThing(): AnotherThing {
                return AnotherThing()
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-18 18:47

    A little addition to Jeff's solution above:

    you may create inner interface instead of static inner class, like this:

    @Module(includes = AppModule.BindsModule.class)
    public class AppModule {
        // usual non-static @Provides
        @Provides
        @Singleton
        Checkout provideCheckout(Billing billing, Products products) {
            return Checkout.forApplication(billing, products);
        }
        // interface with @Binds
        @Module
        public interface BindsModule {
            @Binds
            ISettings bindSettings(Settings settings);
        }
    }
    
    0 讨论(0)
提交回复
热议问题