You can override @Module class, for example for tests.

But annotations on overridden @Provides methods eg @Singleton , @Named , etc won't override original ones because Dagger 2 generates code for initial @Module + @Component classes (for @Module mentioned in @Component(modules = …) .

Yes, you can pass overridden implementations when you build an instance of @Component but it won't affect generated code.

Example, main code

@Module public class SomeModule { @Provides @NonNull @Named("very_special_thing") @Singleton public SomeThing provideSomeThing(@NonNull SomeArgs someArgs) { return new SomeThing(someArgs); } } @Component(modules = SomeModule.class) public interface SomeComponent { void inject(@NonNull TargetClass target); }

In tests

// No need for @Module annotation public class SomeModuleForTest extends SomeModule { // No need for DI annotations here. // Even if you put annotations like @Named, @Singleton, etc // they won't affect generated code so you can't override this behavior of original @Module class. @Override public SomeThing provideSomeThing(@NonNull SomeArgs someArgs) { return mock(SomeThing.class); } }

Then you can pass overridden module:

SomeComponent someComponent = new DaggerSomeComponent.Builder() .someModule(new SomeModuleForTest()) .build();

That's it. Mostly it does not matter since you want same behavior in TestModule as the original @Module , but JFYI ¯_(ツ)_/¯.

Moreover, looks like it's not possible to support such feature easily because actually, scoping annotations affect code generated for a @Component , not the @Module .

https://twitter.com/artem_zin