Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between the @Singleton in module and @Singleton in component in Dagger 2

Im learning Dagger 2, i have noticed that in some examples there is a @Singleton in the module's methods and on other @Singleton on the Component's methods? What is the difference and what exactly a @Singleton annotation on a module's method and on an component's method mean?

like image 477
user1796624 Avatar asked Oct 30 '22 01:10

user1796624


1 Answers

Since you're a beginner, I highly recommend just trying stuff. Writing unit tests is easy enough, and it helps to understand and prove theories.

If you didn't already, read the User's Guide for some basic knowledge about dagger and scopes.

Annotating methods in components (provision methods) doesn't have any effect. You will have to annotate the class or providing method in a module. I want to quickly show how you can just quickly prove this yourself:

We have 2 Component, one using a scope @Singleton, the other one none:

@Singleton
@Component(modules = SingletonModule.class)
public interface SingletonComponent {

    Object getObject();
}

@Component(modules = NormalModule.class)
public interface NormalComponent {

    @Singleton
    Object getObject();

}

With those components come 2 modules, one providing the singleton scoped object (same as the component) the other one just uses no scope:

@Module
public class SingletonModule {

    @Provides
    @Singleton
    public Object provideObject() {
        return new Object();
    }
}

@Module
public class NormalModule {

    @Provides
    public Object provideObject() {
        return new Object();
    }
}

And now we just create a small test:

public class ComponentTest {

    @Test
    public void testSingletonComponent() {
        SingletonComponent component = DaggerSingletonComponent.create();

        Assert.assertEquals(component.getObject(), component.getObject());
    }


    @Test
    public void testNormalComponent() {
        NormalComponent component = DaggerNormalComponent.create();

        Assert.assertNotSame(component.getObject(), component.getObject());
    }
}

This test will succeed and prove that annotating methods in components doesn't do anything. Scoping objects in modules, or annotating the class itself when using constructor injection will result in the object being reused within the same scope / the same component.

Creating 2 components of the same scope will also lead to duplicate objects, as can be proven like this:

@Test
public void testTwoSingleonComponents() {
    SingletonComponent component1 = DaggerSingletonComponent.create();
    SingletonComponent component2 = DaggerSingletonComponent.create();

    Assert.assertNotSame(component1.getObject(), component2.getObject());
}

Be sure to read some tutorials and be sure to try things out. The compiler will complain if you do things wrong! :)

like image 67
David Medenjak Avatar answered Nov 09 '22 08:11

David Medenjak