0
votes

I'm new to dagger, I decided to use one of my many adapters as training for learning dagger 2, this adapter takes a few objects in its constructor which I've annotated with @Inject

@Inject
public CardAdapter(
        ItemTouchListener onItemTouchListener,
        @Named(layoutIdentifierName) String layoutIdentifier,
        TypeFactory typeFactory
        RequestManager glide,
) {
    this.onItemTouchListener = onItemTouchListener;
    this.layoutIdentifier = layoutIdentifier;
    this.typeFactory = typeFactory;
    this.elements = new ArrayList<>();
    this.glide = glide;
}

Glide is the one I'm having trouble with I'll come to it last.

First is OnItemTouchListener, It's an interface implemented in my fragment, I've created a module for this. It's an abstract class with an abstract method annotated with @Binds and included in my components (adapters) modules

COMPONENT

@Component(modules = ItemTouchListenerModule.class)

MODULE

@Module
public abstract class ItemTouchListenerModule {

@Binds
abstract ItemTouchListener provideCardHolderFragmentItemTouchListener(CardHolderFragment cardHolderFragment);

}

Next is the layoutIdentifier its just a string but it changes at runtime so I've made my component have its own builder and given it a method so I can set this at runtime,

@BindsInstance
Builder layoutIdentifier(@Named(layoutIdentifierName) String layoutIdentifier);

Next is the TypeFactory, this is an interface, This is another module with an @Binds annotation

@Module
public abstract class TypeFactoryModule {
     @Binds
     abstract TypeFactory bindTypeFactory(TypeFactoryForList typeFactoryForList);
}

And last, (the one I'm having issues with,) is glide, I'm actually looking to provide the RequestManager, I created a module for it like this

@Module
public class GlideModule {

    public static final String glideContextName = "glide context";
    private Context context;

    public GlideModule(@Named(glideContextName) Context context) {
        this.context = context;
    }

    @Provides
    RequestManager provideGlide(){
         return Glide.with(context);
    }
}

but if I include this in my components modules and add a method in the custom builder and build it, it gives me an error

 error: @Component.Builder is missing setters for required modules or components: [com.sealstudios.simpleaac.dagger.GlideModule]
interface Builder {

here is my component, any ideas? also an explanation would be nice i dont think i get everything that happens here, many thanks

@Component(modules = {TypeFactoryModule.class, ItemTouchListenerModule.class, 
GlideModule.class})
public interface CardAdapterComponent {

String layoutIdentifierName = "layout identifier";
CardAdapter getCardAdapter();

void inject(CardHolderFragment cardHolderFragment);

@Component.Builder
interface Builder {

    @BindsInstance
    Builder layoutIdentifier(@Named(layoutIdentifierName) String layoutIdentifier);

    @BindsInstance
    Builder itemTouchListenerModule(CardHolderFragment cardHolderFragment);

    @BindsInstance
    Builder glideModule(Context context);

    CardAdapterComponent build();
}

}

1

1 Answers

0
votes

Actually the problem is with the GlideModule constructor argument. Dagger has no idea about how to inject a module's constructor! Either you can explicitly add a component builder method receiving the explicit GlideModule object or you can just change GlideModule as below,

@Module
public class GlideModule {

    public static final String glideContextName = "glide context";

    @Provides
    RequestManager provideGlide(Context context){
         return Glide.with(context);
    }
}

Now you can simply pass the context in the component's builder method. Dagger will recognize the Context object type and appropriately pass to the provideGlide method and it should work as expected.